mirror of
https://github.com/esphome/esphome.git
synced 2026-08-17 02:47:52 +08:00
Normalize marker-wrapped callable keys in the schema dump (#18218)
This commit is contained in:
@@ -1134,13 +1134,29 @@ def convert_keys(converted, schema, path):
|
||||
else:
|
||||
converted["key"] = "String"
|
||||
key_string_match = re.search(
|
||||
r"<function (\w*) at \w*>", str(k), re.IGNORECASE
|
||||
r"<function ([^ ]+) at \w+>", str(k), re.IGNORECASE
|
||||
)
|
||||
if key_string_match:
|
||||
converted["key_type"] = key_string_match.group(1)
|
||||
else:
|
||||
converted["key_type"] = str(k)
|
||||
|
||||
# A marker-wrapped callable key (e.g. script.execute's
|
||||
# ``cv.Optional(validate_parameter_name)``) is a wildcard matcher;
|
||||
# ``str(marker)`` is the function repr, whose heap address would
|
||||
# churn the dump every build. Normalize like the bare-callable
|
||||
# branch above: record the validator name in ``key_type`` and file
|
||||
# the config var under ``string``.
|
||||
key_name = str(k)
|
||||
if isinstance(k, vol.Marker) and callable(k.schema):
|
||||
key_string_match = re.search(
|
||||
r"<function ([^ ]+) at \w+>", key_name, re.IGNORECASE
|
||||
)
|
||||
result["key_type"] = (
|
||||
key_string_match.group(1) if key_string_match else key_name
|
||||
)
|
||||
key_name = "string"
|
||||
|
||||
# ``cv.OnlyWith`` / ``cv.OnlyWithout`` expose ``default`` as
|
||||
# a property that returns ``vol.UNDEFINED`` when the gating
|
||||
# component isn't loaded — and at schema-generation time
|
||||
@@ -1220,7 +1236,7 @@ def convert_keys(converted, schema, path):
|
||||
for base_k, base_v in get_overridden_config(k, converted).items():
|
||||
if base_k in result and base_v == result[base_k]:
|
||||
result.pop(base_k)
|
||||
converted["schema"][S_CONFIG_VARS][str(k)] = result
|
||||
converted["schema"][S_CONFIG_VARS][key_name] = result
|
||||
if "key" in converted and converted["key"] == "String":
|
||||
config_vars = converted["schema"]["config_vars"]
|
||||
assert len(config_vars) == 1
|
||||
|
||||
@@ -3,11 +3,13 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import ast
|
||||
from collections.abc import Callable
|
||||
import importlib.util
|
||||
import json
|
||||
from pathlib import Path
|
||||
import subprocess
|
||||
import sys
|
||||
from typing import Any
|
||||
|
||||
import pytest
|
||||
|
||||
@@ -205,6 +207,47 @@ def test_convert_keys_no_marker_for_non_sensitive_field() -> None:
|
||||
assert "sensitive_source" not in entry
|
||||
|
||||
|
||||
def _wildcard_validator(value: Any) -> Any:
|
||||
return value
|
||||
|
||||
|
||||
def test_convert_keys_marker_wrapped_callable_key_normalizes() -> None:
|
||||
converted: dict = {}
|
||||
_bls.convert_keys(converted, {cv.Optional(_wildcard_validator): cv.string}, "/root")
|
||||
|
||||
config_vars = converted["schema"]["config_vars"]
|
||||
assert set(config_vars) == {"string"}
|
||||
assert config_vars["string"]["key"] == "Optional"
|
||||
assert config_vars["string"]["key_type"] == "_wildcard_validator"
|
||||
|
||||
|
||||
def test_convert_keys_marker_wrapped_callable_beside_fixed_keys() -> None:
|
||||
converted: dict = {}
|
||||
_bls.convert_keys(
|
||||
converted,
|
||||
{cv.Required("id"): cv.string, cv.Optional(_wildcard_validator): cv.string},
|
||||
"/root",
|
||||
)
|
||||
|
||||
assert set(converted["schema"]["config_vars"]) == {"id", "string"}
|
||||
|
||||
|
||||
def test_convert_keys_bare_callable_dotted_qualname() -> None:
|
||||
def make_validator() -> Callable[[Any], Any]:
|
||||
def validator(value: Any) -> Any:
|
||||
return value
|
||||
|
||||
return validator
|
||||
|
||||
converted: dict = {}
|
||||
_bls.convert_keys(converted, {make_validator(): cv.string}, "/root")
|
||||
|
||||
assert converted["key"] == "String"
|
||||
assert converted["key_type"].endswith("make_validator.<locals>.validator")
|
||||
assert "at 0x" not in converted["key_type"]
|
||||
assert set(converted["schema"]["config_vars"]) == {"string"}
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Regression tests for the lvgl schema dump.
|
||||
#
|
||||
|
||||
Reference in New Issue
Block a user