diff --git a/snakemake/modules.py b/snakemake/modules.py index b3d84afa3..5bfbb971a 100644 --- a/snakemake/modules.py +++ b/snakemake/modules.py @@ -131,6 +131,7 @@ class WorkflowModifier: def __init__( self, workflow, + parent_modifier=None, globals=None, config=None, base_snakefile=None, @@ -146,12 +147,29 @@ def __init__( replace_wrapper_tag=None, namespace=None, ): + if parent_modifier is not None: + # init with values from parent modifier + self.base_snakefile = parent_modifier.base_snakefile + self.globals = parent_modifier.globals + self.skip_configfile = parent_modifier.skip_configfile + self.rulename_modifier = parent_modifier.rulename_modifier + self.skip_validation = parent_modifier.skip_validation + self.skip_global_report_caption = parent_modifier.skip_global_report_caption + self.rule_whitelist = parent_modifier.rule_whitelist + self.ruleinfo_overwrite = parent_modifier.ruleinfo_overwrite + self.allow_rule_overwrite = parent_modifier.allow_rule_overwrite + self.path_modifier = parent_modifier.path_modifier + self.replace_wrapper_tag = parent_modifier.replace_wrapper_tag + self.namespace = parent_modifier.namespace + else: + # default settings for globals if not inheriting from parent + self.globals = ( + globals if globals is not None else dict(workflow.vanilla_globals) + ) + self.workflow = workflow self.base_snakefile = base_snakefile - self.globals = ( - globals if globals is not None else dict(workflow.vanilla_globals) - ) if config is not None: self.globals["config"] = config diff --git a/snakemake/workflow.py b/snakemake/workflow.py index 3004e5b77..d69ac8332 100644 --- a/snakemake/workflow.py +++ b/snakemake/workflow.py @@ -1933,6 +1933,7 @@ def decorate(maybe_ruleinfo): ruleinfo = maybe_ruleinfo if not callable(maybe_ruleinfo) else None with WorkflowModifier( self, + parent_modifier=self.modifier, rulename_modifier=get_name_modifier_func( rules, name_modifier, parent_modifier=self.modifier ), diff --git a/tests/test01/Snakefile b/tests/test01/Snakefile index 514628a04..cc3eb7b16 100644 --- a/tests/test01/Snakefile +++ b/tests/test01/Snakefile @@ -1,3 +1,4 @@ + from snakemake.utils import min_version from snakemake import __version__ @@ -27,6 +28,8 @@ onerror: print(log) + + ruleorder: rule2 > rule4 def testin(wildcards): diff --git a/tests/test_google_lifesciences.py b/tests/test_google_lifesciences.py index 63a75a410..5d8ca5ca0 100644 --- a/tests/test_google_lifesciences.py +++ b/tests/test_google_lifesciences.py @@ -57,9 +57,13 @@ def create_google_storage(bucket_name="snakemake-testing"): return client.create_bucket(bucket_name) +def get_temp_bucket_name(): + return "snakemake-testing-%s-bucket" % next(tempfile._get_candidate_names()) + + @google_credentials def test_google_lifesciences(): - bucket_name = "snakemake-testing-%s" % next(tempfile._get_candidate_names()) + bucket_name = get_temp_bucket_name() create_google_storage(bucket_name) storage_prefix = "test_google_lifesciences" workdir = dpath("test_google_lifesciences") @@ -82,7 +86,7 @@ def test_google_lifesciences(): ) @google_credentials def test_touch_remote_prefix(): - bucket_name = "snakemake-testing-%s-bucket" % next(tempfile._get_candidate_names()) + bucket_name = get_temp_bucket_name() create_google_storage(bucket_name) storage_prefix = "test_touch_remote_prefix" workdir = dpath("test_touch_remote_prefix") @@ -101,7 +105,7 @@ def test_touch_remote_prefix(): @google_credentials def test_cloud_checkpoints_issue574(): """see Github issue #574""" - bucket_name = "snakemake-testing-%s" % next(tempfile._get_candidate_names()) + bucket_name = get_temp_bucket_name() create_google_storage(bucket_name) storage_prefix = "test_cloud_checkpoints_issue574" workdir = dpath("test_cloud_checkpoints_issue574") @@ -118,7 +122,7 @@ def test_cloud_checkpoints_issue574(): def test_github_issue1396(): - bucket_name = "snakemake-testing-%s" % next(tempfile._get_candidate_names()) + bucket_name = get_temp_bucket_name() create_google_storage(bucket_name) storage_prefix = "test_github_issue1396" workdir = dpath("test_github_issue1396") @@ -135,7 +139,7 @@ def test_github_issue1396(): def test_github_issue1460(): - bucket_name = "snakemake-testing-%s" % next(tempfile._get_candidate_names()) + bucket_name = get_temp_bucket_name() create_google_storage(bucket_name) storage_prefix = "test_github_issue1460" prefix = "%s/%s" % (bucket_name, storage_prefix) diff --git a/tests/test_rule_inheritance_globals/.snakemake/metadata/Zm9vLnR4dA== b/tests/test_rule_inheritance_globals/.snakemake/metadata/Zm9vLnR4dA== new file mode 100644 index 000000000..dafd1c892 --- /dev/null +++ b/tests/test_rule_inheritance_globals/.snakemake/metadata/Zm9vLnR4dA== @@ -0,0 +1 @@ +{"version": null, "code": "gASVqgEAAAAAAAAoQxJ0AGQBfA58EWQCjQMBAGQAUwCUKIwFaW5wdXSUjAZvdXRwdXSUjAZwYXJhbXOUjAl3aWxkY2FyZHOUjAd0aHJlYWRzlIwJcmVzb3VyY2VzlIwDbG9nlIwHdmVyc2lvbpSMBHJ1bGWUjAljb25kYV9lbnaUjA1jb250YWluZXJfaW1nlIwQc2luZ3VsYXJpdHlfYXJnc5SMD3VzZV9zaW5ndWxhcml0eZSMC2Vudl9tb2R1bGVzlIwMYmVuY2hfcmVjb3JklIwFam9iaWSUjAhpc19zaGVsbJSMD2JlbmNoX2l0ZXJhdGlvbpSMD2NsZWFudXBfc2NyaXB0c5SMCnNoYWRvd19kaXKUjA1lZGl0X25vdGVib29rlIwPY29uZGFfYmFzZV9wYXRolIwHYmFzZWRpcpSMGHJ1bnRpbWVfc291cmNlY2FjaGVfcGF0aJSMGF9faXNfc25ha2VtYWtlX3J1bGVfZnVuY5R0lF2UKE6MH2VjaG8gdGVzdCAne2NvbmZpZ30nID4ge291dHB1dH2UaA9oEoaUZYwFc2hlbGyUhZR0lC4=", "rule": "b", "input": [], "log": [], "params": [], "shellcmd": "echo test '{}' > foo.txt", "incomplete": false, "starttime": 1651478820.4933672, "endtime": 1651478820.5000339, "job_hash": 8740185748842, "conda_env": null, "container_img_url": null} \ No newline at end of file diff --git a/tests/test_rule_inheritance_globals/Snakefile b/tests/test_rule_inheritance_globals/Snakefile new file mode 100644 index 000000000..a8f62e5a3 --- /dev/null +++ b/tests/test_rule_inheritance_globals/Snakefile @@ -0,0 +1,10 @@ +rule a: + output: + "test.out" + shell: + "echo test '{config}' > {output}" + + +use rule a as b with: + output: + report("foo.txt", caption="caption.rst") diff --git a/tests/test_rule_inheritance_globals/caption.rst b/tests/test_rule_inheritance_globals/caption.rst new file mode 100644 index 000000000..e69de29bb diff --git a/tests/test_rule_inheritance_globals/expected-results/report.html b/tests/test_rule_inheritance_globals/expected-results/report.html new file mode 100644 index 000000000..e69de29bb diff --git a/tests/test_rule_inheritance_globals/foo.txt b/tests/test_rule_inheritance_globals/foo.txt new file mode 100644 index 000000000..624ce9aa4 --- /dev/null +++ b/tests/test_rule_inheritance_globals/foo.txt @@ -0,0 +1 @@ +test {} diff --git a/tests/tests.py b/tests/tests.py index edc285838..855051ab5 100644 --- a/tests/tests.py +++ b/tests/tests.py @@ -1614,3 +1614,12 @@ def test_cleanup_metadata_fail(): @skip_on_windows # same on win, no need to test def test_github_issue1389(): run(dpath("test_github_issue1389"), resources={"foo": 4}, shouldfail=True) + + +def test_rule_inheritance_globals(): + run( + dpath("test_rule_inheritance_globals"), + report="report.html", + targets=["foo.txt"], + check_md5=False, + )