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:
- 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.
- 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.
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 objectat line 79 here:snakemake/src/snakemake/ruleinfo.py
Lines 75 to 80 in 17f0d9b
A quick fix can be made by checking where the original rule has the
paramsby:Logs
Minimal example
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:
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:OVERWRITEandINHERIT.UseRuleWith.OVERWRITEas the first modified positional argument, it will forcibly overwrite existing values.UseRuleWith.INHERITis provided as the first modified positional argument, it will preserve arguments from the original rule.