🐛 Nested config parsed as string when using --config
If nested config is passed to Snakemake via the --config flag all values are interpreted as strings.
$ snakemake --config test={'test_bool': True, 'int_test': 1}
'test': {'test_bool': 'True', 'int_test': '1'} # Note strings
This is because the yaml parser is using the BaseLoader which does not convert YAML scalars to their corresponding Python types (instead returning them as strings).
If I update the yaml parser to use SafeLoader then the expected behaviour is achieved.
- yaml_base_load = lambda s: yaml.load(s, Loader=yaml.loader.B̶a̶s̶e̶L̶o̶a̶d̶e̶r̶)
+ yaml_base_load = lambda s: yaml.load(s, Loader=yaml.loader.SafeLoader)
$ snakemake --config test={'test_bool': True, 'int_test': 1}
'test': {'test_bool': True, 'int_test': 1} # Note correct types
Should I submit a PR to fix this issue?
SafeLoader DateTime auto-conversion should potentially be switched switched-off as per https://github.com/snakemake/snakemake/pull/709#issuecomment-730336048
Just ran into this issue! Here is a safe loader I have used in the past which does not convert datetime strings to datetime objects
import datetime
import yaml
class SafeLoaderTimestamp(yaml.SafeLoader):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.add_constructor("tag:yaml.org,2002:timestamp", self.construct_yaml_str)
@staticmethod
def construct_yaml_str(loader, node):
return loader.construct_scalar(node)
data = yaml.load('{date: 2019-01-01, number: 1.01}', Loader=SafeLoaderTimestamp)
assert isinstance(data["date"], str)
assert isinstance(data["number"], float)
data = yaml.load('{date: 2019-01-01, number: 1.01}', Loader=yaml.SafeLoader)
assert isinstance(data["date"], datetime.date)
assert isinstance(data["number"], float)
data = yaml.load('{date: 2019-01-01, number: 1.01}', Loader=yaml.BaseLoader)
assert isinstance(data["date"], str)
assert isinstance(data["number"], str)