Skip to content

Commit 8c4641c

Browse files
committed
fix: preserve named params when loading rule args
rule.expand_params returns (params, non_derived_params) in current snakemake; passing the tuple straight into Params() dropped both items in as unnamed positional values, so snakemake.params["<name>"] raised AttributeError. Index [0] like expand_input/expand_output already do.
1 parent fa1eef6 commit 8c4641c

4 files changed

Lines changed: 44 additions & 1 deletion

File tree

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,3 +108,6 @@ slurm*out
108108
# intellij
109109
.idea
110110

111+
# devcontainer-bound conda env
112+
.devcontainer/devenv/
113+

snakemk_util/rule_args.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -229,7 +229,7 @@ def load_rule_args(
229229
smk_resources = rule.expand_resources(default_wildcards, smk_input, attempt=1)
230230
smk_threads = smk_resources._cores
231231
smk_output = OutputFiles(rule.expand_output(default_wildcards)[0])
232-
smk_params = Params(rule.expand_params(default_wildcards, smk_input, smk_output, None))
232+
smk_params = Params(rule.expand_params(default_wildcards, smk_input, smk_output, None)[0])
233233
smk_log = rule.log
234234
smk_config = workflow.config
235235

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
ds_config = {"testdir": {"assembly": "GRCh37"}}
2+
3+
rule all:
4+
input:
5+
"testdir/out.txt"
6+
7+
rule samplerule:
8+
output:
9+
of="{ds_dir}/out.txt"
10+
input:
11+
params:
12+
assembly=lambda wildcards: ds_config[wildcards.ds_dir]["assembly"],
13+
output_basedir="some/base",
14+
nb_script="script.py",
15+
shell:
16+
"echo 'OK' > {output.of}"

tests/test_rule_args.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,30 @@ def test_rule_args_workdir_pythonrule(workflow_dir):
8989
assert os.path.isdir(workflow_dir + "/testdir")
9090

9191

92+
def test_named_params(workflow_dir):
93+
"""Regression test: named params in a rule must be addressable by name on
94+
the loaded Snakemake object. Previously the tuple returned by
95+
rule.expand_params was passed to Params() without indexing [0], which
96+
stripped all names and surfaced as `AttributeError: 'Params' object has
97+
no attribute '<name>'` when accessing snakemake.params["<name>"].
98+
"""
99+
workflow_dir = copy_data(workflow_dir, "test_named_params")
100+
101+
snakefile_path = workflow_dir + "/Snakefile"
102+
103+
snakemake = load_rule_args(
104+
snakefile=snakefile_path,
105+
rule_name="samplerule",
106+
default_wildcards={"ds_dir": "testdir"},
107+
)
108+
109+
assert list(snakemake.params.keys()) == ["assembly", "output_basedir", "nb_script"]
110+
assert snakemake.params["assembly"] == "GRCh37"
111+
assert snakemake.params.assembly == "GRCh37"
112+
assert snakemake.params["output_basedir"] == "some/base"
113+
assert snakemake.params["nb_script"] == "script.py"
114+
115+
92116
def test_output_args(workflow_dir):
93117
workflow_dir = copy_data(workflow_dir, "test_output_args")
94118

0 commit comments

Comments
 (0)