Skip to content
Snippets Groups Projects
Commit 73d4d222 authored by Alexander Schlemmer's avatar Alexander Schlemmer
Browse files

ENH: enhanced macro format

parent 74f4e7ef
No related branches found
No related tags found
2 merge requests!53Release 0.1,!25F macros
Pipeline #23203 passed with warnings
from .macro_yaml_object import defmacro_constructor, macro_constructor, multimacro_constructor
from .macro_yaml_object import defmacro_constructor, macro_constructor
......@@ -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"]
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 "params" in value:
params.update(value["params"])
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)
"""
res = dict()
for val in node.value:
res.update(macro_constructor(loader, val))
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 res
......@@ -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"
......@@ -170,7 +165,7 @@ defs:
testnode:
obl: !macro
name: test
test:
""", Loader=yaml.SafeLoader)
print(yaml.dump(dat))
assert dat["testnode"]["obl"]["replaced1"]["c"]["t1"] == "a"
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment