[libretiny] Give each platform its own CONFIG_SCHEMA instance (#18056)

This commit is contained in:
J. Nick Koston
2026-08-04 11:05:04 -05:00
committed by GitHub
parent 37b6578259
commit c2ddc17063
5 changed files with 56 additions and 6 deletions
+5 -1
View File
@@ -51,7 +51,11 @@ def _set_core_data(config):
return config
CONFIG_SCHEMA = libretiny.BASE_SCHEMA
# extend({}) makes this platform's own schema instance: BASE_SCHEMA is shared
# by every LibreTiny platform, and prepending this platform's _set_core_data
# onto the shared object would run it for every platform's validation once two
# platform modules are imported in one process (device-builder, tests).
CONFIG_SCHEMA = libretiny.BASE_SCHEMA.extend({})
PIN_SCHEMA = libretiny.gpio.BASE_PIN_SCHEMA
@@ -65,6 +65,10 @@ def _set_core_data(config):
return config
# extend({}) makes this platform's own schema instance: BASE_SCHEMA is shared
# by every LibreTiny platform, and prepending this platform's _set_core_data
# onto the shared object would run it for every platform's validation once two
# platform modules are imported in one process (device-builder, tests).
CONFIG_SCHEMA = {SCHEMA}
PIN_SCHEMA = {PIN_SCHEMA}
@@ -117,7 +121,7 @@ VAR_GPIO_PIN = "validate_pin"
VAR_GPIO_USAGE = "validate_usage"
# lines for code snippets
SCHEMA_BASE = "libretiny.BASE_SCHEMA"
SCHEMA_BASE = "libretiny.BASE_SCHEMA.extend({})"
SCHEMA_EXTRA = f"libretiny.BASE_SCHEMA.extend({VAR_SCHEMA})"
PIN_SCHEMA_BASE = "libretiny.gpio.BASE_PIN_SCHEMA"
PIN_SCHEMA_EXTRA = f"libretiny.BASE_PIN_SCHEMA.extend({VAR_PIN_SCHEMA})"
+5 -1
View File
@@ -51,7 +51,11 @@ def _set_core_data(config):
return config
CONFIG_SCHEMA = libretiny.BASE_SCHEMA
# extend({}) makes this platform's own schema instance: BASE_SCHEMA is shared
# by every LibreTiny platform, and prepending this platform's _set_core_data
# onto the shared object would run it for every platform's validation once two
# platform modules are imported in one process (device-builder, tests).
CONFIG_SCHEMA = libretiny.BASE_SCHEMA.extend({})
PIN_SCHEMA = libretiny.gpio.BASE_PIN_SCHEMA
+5 -1
View File
@@ -51,7 +51,11 @@ def _set_core_data(config):
return config
CONFIG_SCHEMA = libretiny.BASE_SCHEMA
# extend({}) makes this platform's own schema instance: BASE_SCHEMA is shared
# by every LibreTiny platform, and prepending this platform's _set_core_data
# onto the shared object would run it for every platform's validation once two
# platform modules are imported in one process (device-builder, tests).
CONFIG_SCHEMA = libretiny.BASE_SCHEMA.extend({})
PIN_SCHEMA = libretiny.gpio.BASE_PIN_SCHEMA
+36 -2
View File
@@ -2,7 +2,8 @@
import pytest
from esphome.components.libretiny import _detect_variant
from esphome.components import bk72xx, ln882x, rtl87xx
from esphome.components.libretiny import BASE_SCHEMA, _detect_variant
from esphome.components.libretiny.const import (
FAMILY_LN882H,
KEY_COMPONENT_DATA,
@@ -11,7 +12,7 @@ from esphome.components.libretiny.const import (
from esphome.components.ln882x import COMPONENT_DATA
import esphome.config_validation as cv
from esphome.const import CONF_BOARD, CONF_FAMILY
from esphome.core import CORE
from esphome.core import CORE, KEY_CORE
@pytest.fixture
@@ -50,3 +51,36 @@ def test_detect_variant_unknown_board_still_raises(ln882x_core_data: None) -> No
"""Ids outside the rename map keep the family-override error."""
with pytest.raises(cv.Invalid, match="This board is unknown"):
_detect_variant({CONF_BOARD: "not-a-real-board"})
def test_platform_schemas_are_isolated_instances() -> None:
"""Each LibreTiny platform must own its CONFIG_SCHEMA instance.
BASE_SCHEMA is shared; every platform prepends its own _set_core_data
extra. On the shared object, importing two platform modules in one process
made either platform's validation run both extras, so the wrong platform's
component data won and known boards failed to resolve.
"""
platforms = (bk72xx, ln882x, rtl87xx)
schemas = [platform.CONFIG_SCHEMA for platform in platforms]
assert len({id(schema) for schema in (BASE_SCHEMA, *schemas)}) == 4
# The shared base must not have accumulated any platform's extra.
# prepend_extra wraps validators in _Schema, so unwrap before comparing.
base_extras = [extra.schema for extra in BASE_SCHEMA._extra_schemas]
for platform in platforms:
assert platform._set_core_data not in base_extras
def test_each_platform_resolves_its_own_boards() -> None:
"""Validating one platform's config must leave that platform's component
data in CORE.data. On the shared schema, the last-imported platform's
_set_core_data won for every platform, so known boards failed to resolve
with "This board is unknown"."""
CORE.data[KEY_CORE] = {} # written by the schema's _update_core_data extra
for platform, board in (
(ln882x, "generic-ln882h"),
(bk72xx, "generic-bk7252"),
(rtl87xx, "generic-rtl8720cf-2mb-896k"),
):
platform.CONFIG_SCHEMA({CONF_BOARD: board})
assert CORE.data[KEY_LIBRETINY][KEY_COMPONENT_DATA] is platform.COMPONENT_DATA