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: updating of non-dict config values gives error #2364

Merged
merged 10 commits into from Aug 5, 2023
24 changes: 15 additions & 9 deletions snakemake/utils.py
Expand Up @@ -479,7 +479,7 @@ def min_version(version):


def update_config(config, overwrite_config):
"""Recursively update dictionary config with overwrite_config.
"""Recursively update dictionary config with overwrite_config in-place.

See
https://stackoverflow.com/questions/3232943/update-value-of-a-nested-dictionary-of-varying-depth
Expand All @@ -488,18 +488,24 @@ def update_config(config, overwrite_config):
Args:
config (dict): dictionary to update
overwrite_config (dict): dictionary whose items will overwrite those in config

"""

def _update(d, u):
for key, value in u.items():
def _update_config(config, overwrite_config):
"""Necessary as recursive calls require a return value,
but `update_config()` has no return value.
"""
for key, value in overwrite_config.items():
if not isinstance(config, collections.abc.Mapping):
# the config cannot be updated as it is no dict
# -> just overwrite it with the new value
config = {}
if isinstance(value, collections.abc.Mapping):
d[key] = _update(d.get(key, {}), value)
sub_config = config.get(key, {})
config[key] = _update_config(sub_config, value)
else:
d[key] = value
return d
config[key] = value
return config

_update(config, overwrite_config)
_update_config(config, overwrite_config)


def available_cpu_count():
Expand Down
2 changes: 2 additions & 0 deletions tests/test_config_merging/config_cmdline_01.yaml
Expand Up @@ -2,3 +2,5 @@ block:
foo: cfg01_foo
bar: cfg01_bar
baz: cfg01_baz
foobar:
cfg01_key: cfg01_val
1 change: 1 addition & 0 deletions tests/test_config_merging/config_snakefile.yaml
@@ -1,3 +1,4 @@
block:
bar: snake_bar
fubar: snake_fubar
foobar: null
2 changes: 1 addition & 1 deletion tests/test_config_merging/expected-results/test.out
@@ -1 +1 @@
{"block": {"bar": "cfg01_bar", "baz": "cfg01_baz", "bowser": "cmdline_bowser", "foo": "cfg02_foo", "fubar": "snake_fubar", "qux": "cfg02_qux", "toad": "cmdline_toad"}}
{"block": {"bar": "cfg01_bar", "baz": "cfg01_baz", "bowser": "cmdline_bowser", "foo": "cfg02_foo", "fubar": "snake_fubar", "qux": "cfg02_qux", "toad": "cmdline_toad", "foobar": {cfg01_key: cfg01_val}}}