Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: ensure that rule inheritance considers the same globals and other settings as parent module #1621

Merged
merged 4 commits into from May 2, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
24 changes: 21 additions & 3 deletions snakemake/modules.py
Expand Up @@ -131,6 +131,7 @@ class WorkflowModifier:
def __init__(
self,
workflow,
parent_modifier=None,
globals=None,
config=None,
base_snakefile=None,
Expand All @@ -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

Expand Down
1 change: 1 addition & 0 deletions snakemake/workflow.py
Expand Up @@ -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
),
Expand Down
3 changes: 3 additions & 0 deletions tests/test01/Snakefile
@@ -1,3 +1,4 @@

from snakemake.utils import min_version

from snakemake import __version__
Expand Down Expand Up @@ -27,6 +28,8 @@ onerror:
print(log)




ruleorder: rule2 > rule4

def testin(wildcards):
Expand Down
14 changes: 9 additions & 5 deletions tests/test_google_lifesciences.py
Expand Up @@ -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")
Expand All @@ -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")
Expand All @@ -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")
Expand All @@ -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")
Expand All @@ -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)
Expand Down
@@ -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}
10 changes: 10 additions & 0 deletions 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")
Empty file.
Empty file.
1 change: 1 addition & 0 deletions tests/test_rule_inheritance_globals/foo.txt
@@ -0,0 +1 @@
test {}
9 changes: 9 additions & 0 deletions tests/tests.py
Expand Up @@ -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,
)