diff --git a/snakemake/path_modifier.py b/snakemake/path_modifier.py index 4ccc1bfc4..54c2dfaf6 100644 --- a/snakemake/path_modifier.py +++ b/snakemake/path_modifier.py @@ -5,7 +5,7 @@ import os from snakemake.exceptions import WorkflowError -from snakemake.io import is_flagged, AnnotatedString, flag, get_flag_value +from snakemake.io import is_callable, is_flagged, AnnotatedString, flag, get_flag_value PATH_MODIFIER_FLAG = "path_modified" @@ -57,6 +57,7 @@ def replace_prefix(self, path, property=None): or os.path.isabs(path) or path.startswith("..") or is_flagged(path, "remote_object") + or is_callable(path) ): # no replacement return path @@ -78,9 +79,9 @@ def replace_prefix(self, path, property=None): else: # no matching prefix return path - - # prefix case - return self.prefix + path + else: + # prefix case + return self.prefix + path def apply_default_remote(self, path): """Apply the defined default remote provider to the given path and return the updated _IOFile. diff --git a/snakemake/rules.py b/snakemake/rules.py index b02d55666..5a13d8ff2 100644 --- a/snakemake/rules.py +++ b/snakemake/rules.py @@ -734,7 +734,7 @@ def apply_input_function( incomplete_checkpoint_func=lambda e: None, raw_exceptions=False, groupid=None, - **aux_params + **aux_params, ): incomplete = False if isinstance(func, _IOFile): @@ -811,7 +811,7 @@ def _apply_wildcards( incomplete_checkpoint_func=incomplete_checkpoint_func, is_unpack=is_unpack, groupid=groupid, - **aux_params + **aux_params, ) if is_unpack and not incomplete: @@ -819,16 +819,19 @@ def _apply_wildcards( raise WorkflowError( "unpack() is not allowed with params. " "Simply return a dictionary which can be directly ." - "used, e.g. via {params[mykey]}." + "used, e.g. via {params[mykey]}.", + rule=self, ) # Sanity checks before interpreting unpack() if not isinstance(item, (list, dict)): raise WorkflowError( - "Can only use unpack() on list and dict", rule=self + f"Can only use unpack() on list and dict, but {item} was returned.", + rule=self, ) if name: raise WorkflowError( - "Cannot combine named input file with unpack()", rule=self + f"Cannot combine named input file (name {name}) with unpack()", + rule=self, ) # Allow streamlined code with/without unpack if isinstance(item, list): @@ -1067,7 +1070,7 @@ def apply(name, res, threads=None): attempt=attempt, incomplete_checkpoint_func=lambda e: 0, raw_exceptions=True, - **aux + **aux, ) except (Exception, BaseException) as e: raise InputFunctionException(e, rule=self, wildcards=wildcards) diff --git a/tests/test_github_issue1498/Snakefile b/tests/test_github_issue1498/Snakefile new file mode 100644 index 000000000..bbd78b5be --- /dev/null +++ b/tests/test_github_issue1498/Snakefile @@ -0,0 +1,22 @@ +rule all: + input: + "results/all.done", + + +module other: + snakefile: + "module.smk" + prefix: + "results/other" + + +use rule * from other as other_* + + +rule all_impl: + output: + out=touch("results/all.done"), + input: + b=rules.other_b.output.b, + shell: + "cp {input} {output}" diff --git a/tests/test_github_issue1498/expected-results/results/all.done b/tests/test_github_issue1498/expected-results/results/all.done new file mode 100644 index 000000000..e69de29bb diff --git a/tests/test_github_issue1498/expected-results/results/other/results/a.txt b/tests/test_github_issue1498/expected-results/results/other/results/a.txt new file mode 100644 index 000000000..e69de29bb diff --git a/tests/test_github_issue1498/expected-results/results/other/results/b.txt b/tests/test_github_issue1498/expected-results/results/other/results/b.txt new file mode 100644 index 000000000..e69de29bb diff --git a/tests/test_github_issue1498/module.smk b/tests/test_github_issue1498/module.smk new file mode 100644 index 000000000..7d67ff533 --- /dev/null +++ b/tests/test_github_issue1498/module.smk @@ -0,0 +1,21 @@ +rule a: + output: + a=touch("results/a.txt"), + + +def unpack_a(wildcards): + return {"a": rules.a.output.a} + + +def lambda_a(wildcards): + return rules.a.output.a + + +rule b: + input: + unpack(unpack_a), + # a = lambda_a, + output: + b="results/b.txt", + shell: + "cp {input.a} {output}" diff --git a/tests/tests.py b/tests/tests.py index 12495ee51..57df7e7b2 100644 --- a/tests/tests.py +++ b/tests/tests.py @@ -1591,5 +1591,9 @@ def test_github_issue1542(): run(dpath("test_github_issue1542"), dryrun=True) +def test_github_issue1498(): + run(dpath("test_github_issue1498")) + + def test_cleanup_metadata_fail(): run(dpath("test09"), cleanup_metadata=["xyz"])