From 73d4d22287ef3955fb8cd02d589b15dc4dbff8a9 Mon Sep 17 00:00:00 2001 From: Alexander Schlemmer <alexander@mail-schlemmer.de> Date: Fri, 20 May 2022 15:39:46 +0200 Subject: [PATCH] ENH: enhanced macro format --- src/caoscrawler/macros/__init__.py | 2 +- src/caoscrawler/macros/macro_yaml_object.py | 51 +++++++++++++-------- unittests/test_macros.py | 27 +++++------ 3 files changed, 43 insertions(+), 37 deletions(-) diff --git a/src/caoscrawler/macros/__init__.py b/src/caoscrawler/macros/__init__.py index 3b01d811..0acfb176 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 056152c9..46e8affe 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 dfb4bd0a..048f0527 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" -- GitLab