From 73bbd75d3fc747e92aff3c6b7647c269157793bf Mon Sep 17 00:00:00 2001 From: Jesse Hills <3060199+jesserockz@users.noreply.github.com> Date: Thu, 8 Oct 2026 17:29:56 +1300 Subject: [PATCH] [core] Let cv.rename_key pass non-dict input through (#20331) --- esphome/config_validation.py | 5 +++++ tests/unit_tests/test_config_validation.py | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/esphome/config_validation.py b/esphome/config_validation.py index 579da9a315..79d7068838 100644 --- a/esphome/config_validation.py +++ b/esphome/config_validation.py @@ -2872,9 +2872,14 @@ def rename_key( When ``removed_in`` is set, a deprecation warning is logged if the old key is present. Pass ``component`` (the platform/component name) alongside ``removed_in`` so the warning identifies where it originates. + + Input that is not a dictionary is returned unchanged, so the schema that + follows reports it as a normal configuration error. """ def validator(config: dict) -> dict: + if not isinstance(config, dict): + return config config = config.copy() if old_key in config: has_at_most_one_key(old_key, new_key)(config) diff --git a/tests/unit_tests/test_config_validation.py b/tests/unit_tests/test_config_validation.py index 230a8e1f9e..742f07c8de 100644 --- a/tests/unit_tests/test_config_validation.py +++ b/tests/unit_tests/test_config_validation.py @@ -3120,6 +3120,11 @@ def test_rename_key_absent() -> None: assert cv.rename_key("old", "new")({"other": 5}) == {"other": 5} +@pytest.mark.parametrize("value", ["an_id", 1, None, ["old"]]) +def test_rename_key_non_dict_passes_through(value: object) -> None: + assert cv.rename_key("old", "new")(value) == value + + def test_rename_key_no_removed_in_is_silent( caplog: pytest.LogCaptureFixture, ) -> None: