From 33987525d40cdf68f9482f71cbded1d6312b2e06 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Ale=C5=A1=20Mr=C3=A1zek?= Date: Mon, 21 Jul 2025 15:42:06 +0200 Subject: [PATCH] parsing: yaml: support for !include in root --- python/knot_resolver/utils/modeling/parsing.py | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/python/knot_resolver/utils/modeling/parsing.py b/python/knot_resolver/utils/modeling/parsing.py index b9c76378a..7f66fbd76 100644 --- a/python/knot_resolver/utils/modeling/parsing.py +++ b/python/knot_resolver/utils/modeling/parsing.py @@ -81,15 +81,31 @@ def construct_include(loader: _RaiseDuplicatesIncludeLoader, node: Any) -> Any: return "".join(file.readlines()) +def include_root(text: str) -> str: + ntext = "" + for line in iter(text.splitlines()): + if line.startswith(_include_key): + file_path = line[len(_include_key) + 1 :] + with open(file_path, "r") as file: + include_text = file.read() + ntext += include_root(include_text) + else: + ntext += line + "\n" + return ntext + + class DataFormat(Enum): YAML = auto() JSON = auto() def parse_to_dict(self, text: str) -> Any: if self is DataFormat.YAML: + # handle root includes separately, pyyaml loader cannot do that + included = include_root(text) + # _RaiseDuplicatesIncludeLoader extends yaml.SafeLoader, so this should be safe # https://python.land/data-processing/python-yaml#PyYAML_safe_load_vs_load - return renamed(yaml.load(text, Loader=_RaiseDuplicatesIncludeLoader)) # type: ignore + return renamed(yaml.load(included, Loader=_RaiseDuplicatesIncludeLoader)) # type: ignore if self is DataFormat.JSON: return renamed(json.loads(text, object_pairs_hook=_json_raise_duplicates)) raise NotImplementedError(f"Parsing of format '{self}' is not implemented") -- 2.47.2