diff --git a/src/caoscrawler/macros/__init__.py b/src/caoscrawler/macros/__init__.py index 0acfb1763039a3bb800bbf0e26d6940b49d045cf..3b01d811953eefcf86854b48eac57f41a3f3b757 100644 --- a/src/caoscrawler/macros/__init__.py +++ b/src/caoscrawler/macros/__init__.py @@ -1 +1 @@ -from .macro_yaml_object import defmacro_constructor, macro_constructor +from .macro_yaml_object import defmacro_constructor, macro_constructor, multimacro_constructor diff --git a/src/caoscrawler/macros/macro_yaml_object.py b/src/caoscrawler/macros/macro_yaml_object.py index 0ed26e5470c9289ac7228a112e764afd53f5e580..80a119ce8f7aeefe702669fd8277a0a2d5b28e30 100644 --- a/src/caoscrawler/macros/macro_yaml_object.py +++ b/src/caoscrawler/macros/macro_yaml_object.py @@ -79,6 +79,8 @@ def substitute_dict(sourced: dict[str, Any], values: dict[str, Any]): for i in d[k]: if isinstance(i, str): subst_list.append(substitute(i, values)) + elif isinstance(i, dict): + subst_list.append(substitute_dict(i, values)) else: subst_list.append(i) d[k] = subst_list @@ -119,3 +121,12 @@ def macro_constructor(loader, node): definition = deepcopy(macro.definition) return substitute_dict(definition, params) + +def multimacro_constructor(loader, node): + """ + Function that can be used to chain macros for complex definitions of dictionaries. + + It can be registered in pyaml using: + yaml.SafeLoader.add_constructor("!multimacro", multimacro_constructor) + """ + pass diff --git a/unittests/test_macros.py b/unittests/test_macros.py index 2beced2f1f701535e70026e9cc760123ff965a0c..b6dbc16b67db6201ab5bcda9b803e4aac7a34f8e 100644 --- a/unittests/test_macros.py +++ b/unittests/test_macros.py @@ -22,12 +22,17 @@ # ** end header # -from caoscrawler.macros import defmacro_constructor, macro_constructor +from caoscrawler.macros import defmacro_constructor, macro_constructor, multimacro_constructor import yaml +import pytest -def test_macros(): +@pytest.fixture +def register_macros(): yaml.SafeLoader.add_constructor("!defmacro", defmacro_constructor) yaml.SafeLoader.add_constructor("!macro", macro_constructor) + yaml.SafeLoader.add_constructor("!multimacro", multimacro_constructor) + +def test_macros(register_macros): dat = yaml.load(""" defs: - !defmacro @@ -52,3 +57,30 @@ testnode: assert dat["testnode"]["obl"]["expanded_yea"]["yea"] == "$variable" assert "expanded_bla" not in dat["testnode"]["obl"] assert "bla" not in dat["testnode"]["obl"]["expanded_yea"] + +def test_macro_list_replacment(register_macros): + dat = yaml.load(""" +defs: +- !defmacro + name: test + params: + a: 2 + b: bla + c: $variable + definition: + expanded_$b: + blubb: + - ok$a + - $b: $c + +testnode: + obl: !macro + name: test + params: + a: 4 + b: yea +""", Loader=yaml.SafeLoader) + assert isinstance(dat["testnode"]["obl"]["expanded_yea"]["blubb"], list) + assert len(dat["testnode"]["obl"]["expanded_yea"]["blubb"]) == 2 + assert dat["testnode"]["obl"]["expanded_yea"]["blubb"][0] == "ok4" + assert dat["testnode"]["obl"]["expanded_yea"]["blubb"][1]["yea"] == "$variable"