diff --git a/src/caoscrawler/macros/__init__.py b/src/caoscrawler/macros/__init__.py index 3b01d811953eefcf86854b48eac57f41a3f3b757..0acfb1763039a3bb800bbf0e26d6940b49d045cf 100644 --- a/src/caoscrawler/macros/__init__.py +++ b/src/caoscrawler/macros/__init__.py @@ -1 +1 @@ -from .macro_yaml_object import defmacro_constructor, macro_constructor, multimacro_constructor +from .macro_yaml_object import defmacro_constructor, macro_constructor diff --git a/src/caoscrawler/macros/macro_yaml_object.py b/src/caoscrawler/macros/macro_yaml_object.py index 056152c9278e0b5e97749bf91523f192a53fc45f..46e8affeb3c2547e6ec8f1aa7f6ecc7952c5aaa1 100644 --- a/src/caoscrawler/macros/macro_yaml_object.py +++ b/src/caoscrawler/macros/macro_yaml_object.py @@ -117,26 +117,37 @@ def macro_constructor(loader, node): It can be registered in pyaml using: yaml.SafeLoader.add_constructor("!macro", macro_constructor) """ + res = dict() value = loader.construct_mapping(node, deep=True) - name = value["name"] - macro = macro_store[name] - params = deepcopy(macro.params) - if "params" in value: - params.update(value["params"]) - definition = deepcopy(macro.definition) + for name, params_setter in value.items(): + if name in macro_store: + # If params_setter is a list, run this for every element: + if params_setter is not None and isinstance(params_setter, list): + for el in params_setter: + macro = macro_store[name] + params = deepcopy(macro.params) + if el is not None: + if isinstance(el, dict): + params.update(el) + else: + raise RuntimeError("params type not supported") + else: + raise RuntimeError("params type must not be None") + definition = substitute_dict(macro.definition, params) + res.update(definition) + else: + # This is just a single macro: + macro = macro_store[name] + params = deepcopy(macro.params) + if params_setter is not None: + if isinstance(params_setter, dict): + params.update(params_setter) + else: + raise RuntimeError("params type not supported") + definition = substitute_dict(macro.definition, params) + res.update(definition) + else: + # If there is no macro with that name, just keep that node: + res[name] = params_setter - 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) - """ - - res = dict() - for val in node.value: - res.update(macro_constructor(loader, val)) - return res diff --git a/unittests/test_macros.py b/unittests/test_macros.py index dfb4bd0a7854e65847d5224641589b5e1a8e04bb..048f05275fa1f5f9025241e746db6bf368030e82 100644 --- a/unittests/test_macros.py +++ b/unittests/test_macros.py @@ -22,9 +22,7 @@ # ** end header # -from caoscrawler.macros import (defmacro_constructor, - macro_constructor, - multimacro_constructor) +from caoscrawler.macros import defmacro_constructor, macro_constructor from caoscrawler.macros.macro_yaml_object import macro_store import yaml import pytest @@ -33,7 +31,6 @@ import pytest def register_macros(): yaml.SafeLoader.add_constructor("!defmacro", defmacro_constructor) yaml.SafeLoader.add_constructor("!macro", macro_constructor) - yaml.SafeLoader.add_constructor("!multimacro", multimacro_constructor) @pytest.fixture def macro_store_reset(): @@ -55,8 +52,7 @@ defs: testnode: obl: !macro - name: test - params: + test: a: 4 b: yea """, Loader=yaml.SafeLoader) @@ -82,8 +78,7 @@ defs: testnode: obl: !macro - name: test - params: + test: a: 4 b: yea """, Loader=yaml.SafeLoader) @@ -108,9 +103,9 @@ defs: replaced3: ok testnode: - obl: !multimacro - - name: test_one - - name: test_two + obl: !macro + test_one: + test_two: """, Loader=yaml.SafeLoader) print(yaml.dump(dat)) assert dat["testnode"]["obl"]["replaced1"] == "ok" @@ -136,9 +131,9 @@ defs: replaced2: ok replaced3: ok -testnode: !multimacro - - name: test_one - - name: test_two +testnode: !macro + test_one: + test_two: """, Loader=yaml.SafeLoader) assert dat["testnode"]["replaced1"] == "ok" assert dat["testnode"]["replaced2"] == "ok" @@ -169,8 +164,8 @@ defs: d: $testvar_list testnode: - obl: !macro - name: test + obl: !macro + test: """, Loader=yaml.SafeLoader) print(yaml.dump(dat)) assert dat["testnode"]["obl"]["replaced1"]["c"]["t1"] == "a"