Skip to content

cannot unpack non-iterable NoneType object from #3365 #3495

@Hocnonsense

Description

@Hocnonsense

Snakemake version
9.1.3

Describe the bug

Consider the snakefile shown below, where the original rule doesn't have params, and used with params redefined.
This will cause a TypeError: cannot unpack non-iterable NoneType object at line 79 here:

if key == "params":
# if positional arguments are used after the 'with' statement
# overwrite all positional arguments of the original rule
# for keyword arguments replace only the ones defined after 'with'
original_positional, original_keyword = self.__dict__["params"]
modifier_positional, modifier_keyword = value

A quick fix can be made by checking where the original rule has the params by:

                    if key == "params" and self.__dict__["params"]:
                        # if positional arguments are used after the 'with' statement
                        # overwrite all positional arguments of the original rule
                        # for keyword arguments replace only the ones defined after 'with'
                        original_positional, original_keyword = self.__dict__["params"]
                        modifier_positional, modifier_keyword = value

Logs

~/software/snakemake$ snakemake -s snakefile two
TypeError in file "/home/hwrn/software/snakemake/snakefile", line 11:
cannot unpack non-iterable NoneType object

Minimal example

rule one:
    output:
        "one.txt",
    shell:
        "echo {params} > {output[0]}"


use rule one as two with:
    params:
        output="goor job",

Additional context
Honestly, I was initially against changing the default behavior of params to prevent overwriting any given parameters in #3338 and #3365. Besides this edge case, which can be easily fixed, I have two additional concerns:

  1. Other rule keywords, such as input, output, and log, also accept multiple named and unnamed arguments. It feels inconsistent to enforce strict behavior only for params while leaving the others unchanged. This inconsistency may make it harder for users to remember the behavior.
  2. In the current version, params defined in the original rule cannot be removed, which can be problematic in certain cases.

To address this, I propose a small revision: introducing a marker that modifies how params are handled. Specifically, I suggest an enum class, UseRuleWith, with two flags: OVERWRITE and INHERIT.

  • When input, output, log, or params receives UseRuleWith.OVERWRITE as the first modified positional argument, it will forcibly overwrite existing values.
  • When UseRuleWith.INHERIT is provided as the first modified positional argument, it will preserve arguments from the original rule.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions