diff --git a/snakemake/rules.py b/snakemake/rules.py index 85f2a3734..1c478cbe7 100644 --- a/snakemake/rules.py +++ b/snakemake/rules.py @@ -787,8 +787,6 @@ def _apply_wildcards( groupid=groupid, **aux_params ) - if apply_path_modifier and not incomplete: - item = self.apply_path_modifier(item, property=property) if is_unpack and not incomplete: if not allow_unpack: @@ -808,14 +806,14 @@ def _apply_wildcards( ) # Allow streamlined code with/without unpack if isinstance(item, list): - pairs = zip([None] * len(item), item) + pairs = zip([None] * len(item), item, [_is_callable] * len(item)) else: assert isinstance(item, dict) - pairs = item.items() + pairs = [(name, item, _is_callable) for name, item in item.items()] else: - pairs = [(name, item)] + pairs = [(name, item, _is_callable)] - for name, item in pairs: + for name, item, from_callable in pairs: is_iterable = True if not_iterable(item) or no_flattening: item = [item] @@ -829,6 +827,10 @@ def _apply_wildcards( raise WorkflowError( "Function did not return str or list " "of str.", rule=self ) + + if from_callable and apply_path_modifier and not incomplete: + item_ = self.apply_path_modifier(item_, property=property) + concrete = concretize(item_, wildcards, _is_callable) newitems.append(concrete) if mapping is not None: diff --git a/tests/test_github_issue1396/Snakefile b/tests/test_github_issue1396/Snakefile new file mode 100644 index 000000000..434704d7f --- /dev/null +++ b/tests/test_github_issue1396/Snakefile @@ -0,0 +1,16 @@ +def get_files(wildcards): + files_1 = expand("file_{i}", i=list(range(1, 5))) + files_2 = expand("file_{i}", i=list(range(5, 9))) + return {"files_1": files_1, "files_2": files_2} + + +rule all: + input: + unpack(get_files), + + +rule make_files: + output: + expand("file_{i}", i=list(range(1, 9))), + shell: + "touch {output}" diff --git a/tests/test_github_issue1396/expected-results/.gitkeep b/tests/test_github_issue1396/expected-results/.gitkeep new file mode 100644 index 000000000..e69de29bb diff --git a/tests/test_google_lifesciences.py b/tests/test_google_lifesciences.py index 47f34d0cb..4c6366e95 100644 --- a/tests/test_google_lifesciences.py +++ b/tests/test_google_lifesciences.py @@ -109,3 +109,20 @@ def test_cloud_checkpoints_issue574(): ) finally: cleanup_google_storage(storage_prefix, bucket_name) + + +def test_github_issue1396(): + bucket_name = "snakemake-testing-%s" % next(tempfile._get_candidate_names()) + create_google_storage(bucket_name) + storage_prefix = "test_github_issue1396" + workdir = dpath("test_github_issue1396") + try: + run( + workdir, + default_remote_prefix="%s/%s" % (bucket_name, storage_prefix), + google_lifesciences=True, + google_lifesciences_cache=False, + dryrun=True, + ) + finally: + cleanup_google_storage(storage_prefix, bucket_name)