[yaml] Add IncludeFile representer to ESPHomeDumper (#15549)

This commit is contained in:
J. Nick Koston
2026-04-07 16:27:11 -10:00
committed by GitHub
parent 2e3ff4e215
commit 4db82877af
2 changed files with 45 additions and 0 deletions
+9
View File
@@ -754,6 +754,14 @@ class ESPHomeDumper(yaml.SafeDumper):
def represent_remove(self, value):
return self.represent_scalar(tag="!remove", value=value.value)
def represent_include_file(self, value):
if value.vars:
mapping = {"file": value.file.as_posix(), "vars": value.vars}
return self.represent_mapping(
tag="!include", mapping=mapping, flow_style=False
)
return self.represent_scalar(tag="!include", value=value.file.as_posix())
def represent_id(self, value):
if is_secret(value.id):
return self.represent_secret(value.id)
@@ -785,3 +793,4 @@ ESPHomeDumper.add_multi_representer(Remove, ESPHomeDumper.represent_remove)
ESPHomeDumper.add_multi_representer(core.ID, ESPHomeDumper.represent_id)
ESPHomeDumper.add_multi_representer(uuid.UUID, ESPHomeDumper.represent_stringify)
ESPHomeDumper.add_multi_representer(Path, ESPHomeDumper.represent_stringify)
ESPHomeDumper.add_multi_representer(IncludeFile, ESPHomeDumper.represent_include_file)
+36
View File
@@ -508,6 +508,42 @@ def test_represent_remove() -> None:
assert yaml_util.dump({"key": Remove("my_id")}) == "key: !remove 'my_id'\n"
def test_represent_include_file() -> None:
"""Test that IncludeFile objects are dumped as !include scalars."""
include = yaml_util.IncludeFile(
Path("/fake/main.yaml"), "path/to/file.yaml", None, lambda _: {}
)
assert yaml_util.dump({"key": include}) == "key: !include 'path/to/file.yaml'\n"
def test_represent_include_file_with_vars() -> None:
"""Test that IncludeFile with vars is dumped as !include mapping form."""
include = yaml_util.IncludeFile(
Path("/fake/main.yaml"),
"path/to/file.yaml",
{"key": "value"},
lambda _: {},
)
result = yaml_util.dump({"key": include})
assert "!include" in result
assert "file: path/to/file.yaml" in result
assert "key: value" in result
def test_represent_include_file_with_data_base_mixin() -> None:
"""Test that IncludeFile wrapped with ESPHomeDataBase mixin is also dumped correctly.
The YAML loader wraps IncludeFile via add_class_to_obj, creating a dynamic
subclass. add_multi_representer must match this subclass through the MRO.
"""
include = yaml_util.IncludeFile(
Path("/fake/main.yaml"), "common/spi.yaml", None, lambda _: {}
)
wrapped = yaml_util.make_data_base(include)
assert isinstance(wrapped, yaml_util.ESPHomeDataBase)
assert yaml_util.dump({"pkg": wrapped}) == "pkg: !include 'common/spi.yaml'\n"
# ── IncludeFile unit tests ──────────────────────────────────────────────────