From 67489f6196ba88eb147e475c423dc9540a3f6453 Mon Sep 17 00:00:00 2001 From: Jesse Hills <3060199+jesserockz@users.noreply.github.com> Date: Tue, 30 Jun 2026 10:34:27 +1200 Subject: [PATCH] [rp2] Address esphbot review suggestions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Ethernet: rename ``RP2040_ETHERNET_TYPES`` → ``RP2_ETHERNET_TYPES`` and ``_RP2040_SPI_LIBRARIES`` → ``_RP2_SPI_LIBRARIES``; update the user-facing validation error from "supported on RP2040" to "supported on the RP2 platform" so RP2350 (Pico 2) users picking an unsupported PHY don't get a misleading message under the family-level gate. * CORE.is_rp2040 now logs a one-shot deprecation warning on first access (deduped via CORE.data) to match the parallel ``cv.only_on_rp2040`` shim. Same removal target (2027.7.0). --- esphome/components/ethernet/__init__.py | 16 +++++++++------- esphome/core/__init__.py | 20 +++++++++++++++++++- tests/unit_tests/test_core.py | 21 ++++++++++++++++----- 3 files changed, 44 insertions(+), 13 deletions(-) diff --git a/esphome/components/ethernet/__init__.py b/esphome/components/ethernet/__init__.py index 4f8abb6b55..dc4cbda45c 100644 --- a/esphome/components/ethernet/__init__.py +++ b/esphome/components/ethernet/__init__.py @@ -179,9 +179,11 @@ _ALWAYS_EXTERNAL_IDF_COMPONENTS = {"LAN8670", "ENC28J60"} # ESP32-only SPI ethernet types (W5100 is RP2040-only, no ESP-IDF driver) SPI_ETHERNET_TYPES = {"W5500", "DM9051", "ENC28J60"} -# RP2040-supported ethernet types (SPI and PIO QSPI) -RP2040_ETHERNET_TYPES = {"W5100", "W5500", "W6100", "W6300", "ENC28J60"} -_RP2040_SPI_LIBRARIES = { +# RP2-supported ethernet types (SPI and PIO QSPI). Applies to the whole +# RP2 family (RP2040 and RP2350); the chip-specific W5100 caveat in the +# comment above is about ESP-IDF driver coverage, not the RP2 platform. +RP2_ETHERNET_TYPES = {"W5100", "W5500", "W6100", "W6300", "ENC28J60"} +_RP2_SPI_LIBRARIES = { "W5100": "lwIP_w5100", "W5500": "lwIP_w5500", "ENC28J60": "lwIP_enc28j60", @@ -361,10 +363,10 @@ def _validate(config): f"{config[CONF_TYPE]} PHY requires RMII interface and is only supported " f"on ESP32 classic and ESP32-P4, not {variant}" ) - elif CORE.is_rp2 and config[CONF_TYPE] not in RP2040_ETHERNET_TYPES: + elif CORE.is_rp2 and config[CONF_TYPE] not in RP2_ETHERNET_TYPES: raise cv.Invalid( - f"Only {', '.join(sorted(RP2040_ETHERNET_TYPES))} are supported on RP2040, " - f"not {config[CONF_TYPE]}" + f"Only {', '.join(sorted(RP2_ETHERNET_TYPES))} are supported on the RP2 " + f"platform, not {config[CONF_TYPE]}" ) return config @@ -670,7 +672,7 @@ async def _to_code_rp2040(var: cg.Pvariable, config: ConfigType) -> None: cg.add(var.set_reset_pin(config[CONF_RESET_PIN])) cg.add_define("USE_ETHERNET_SPI") - cg.add_library(_RP2040_SPI_LIBRARIES[config[CONF_TYPE]], None) + cg.add_library(_RP2_SPI_LIBRARIES[config[CONF_TYPE]], None) def _final_validate_rmii_pins(config: ConfigType) -> None: diff --git a/esphome/core/__init__.py b/esphome/core/__init__.py index a61fa87de0..9ec6e2380f 100644 --- a/esphome/core/__init__.py +++ b/esphome/core/__init__.py @@ -52,6 +52,11 @@ _LOGGER = logging.getLogger(__name__) # Key for tracking controller count in CORE.data for ControllerRegistry StaticVector sizing KEY_CONTROLLER_REGISTRY_COUNT = "controller_registry_count" +# CORE.data key for the "is_rp2040 deprecation warning already fired this +# run" flag. Mirrors the ``cv.only_on_rp2040`` dedupe pattern; cleared +# between runs so each fresh invocation warns once. +_IS_RP2040_DEPRECATED_KEY = "_core_is_rp2040_deprecated_warned" + class EsphomeError(Exception): """General ESPHome exception occurred.""" @@ -843,7 +848,20 @@ class EsphomeCore: """Deprecated: use :attr:`is_rp2` for the family check, or ``rp2.get_rp2040_variant() == rp2.VARIANT_RP2040`` for the variant-specific check. Kept as an alias since pre-RP2350 - callers used it as a family check, identical to ``is_rp2``.""" + callers used it as a family check, identical to ``is_rp2``. + + Scheduled for removal in 2027.7.0. Logs a one-shot deprecation + warning per run (deduped via ``self.data`` so repeated reads in + the same invocation don't spam) to match the parallel + ``cv.only_on_rp2040`` shim. + """ + if not self.data.get(_IS_RP2040_DEPRECATED_KEY): + _LOGGER.warning( + "CORE.is_rp2040 is deprecated; use CORE.is_rp2 for the family " + "gate, or rp2.get_rp2040_variant() == rp2.VARIANT_RP2040 for " + "the variant-specific check. Removed in 2027.7.0." + ) + self.data[_IS_RP2040_DEPRECATED_KEY] = True return self.is_rp2 @property diff --git a/tests/unit_tests/test_core.py b/tests/unit_tests/test_core.py index 6035599e81..0cb0c1f62d 100644 --- a/tests/unit_tests/test_core.py +++ b/tests/unit_tests/test_core.py @@ -599,13 +599,24 @@ class TestEsphomeCore: assert target.is_esp32 is False assert target.is_esp8266 is False - def test_is_rp2040_deprecated_alias_matches_is_rp2(self, target): + def test_is_rp2040_deprecated_alias_matches_is_rp2(self, target, caplog): """``is_rp2040`` is kept as a deprecation shim that returns whatever - ``is_rp2`` returns; both must agree across platform values.""" - target.data[const.KEY_CORE] = {const.KEY_TARGET_PLATFORM: "rp2"} - assert target.is_rp2040 is True - assert target.is_rp2040 == target.is_rp2 + ``is_rp2`` returns; both must agree across platform values. A + one-shot deprecation warning is emitted on first access and + deduped via ``CORE.data`` for the rest of the run.""" + import logging + target.data[const.KEY_CORE] = {const.KEY_TARGET_PLATFORM: "rp2"} + with caplog.at_level(logging.WARNING, logger="esphome.core"): + assert target.is_rp2040 is True + assert target.is_rp2040 == target.is_rp2 + + warnings = [r for r in caplog.records if "is_rp2040" in r.message] + assert len(warnings) == 1 + assert "2027.7.0" in warnings[0].message + + # Reset the dedupe so the False-platform branch also runs the shim. + target.data.pop("_core_is_rp2040_deprecated_warned", None) target.data[const.KEY_CORE] = {const.KEY_TARGET_PLATFORM: "esp32"} assert target.is_rp2040 is False assert target.is_rp2040 == target.is_rp2