diff --git a/esphome/arduino8266/framework.py b/esphome/arduino8266/framework.py index e7b55e1b7c..cded1438c4 100644 --- a/esphome/arduino8266/framework.py +++ b/esphome/arduino8266/framework.py @@ -68,9 +68,12 @@ def framework_package_version(ver: Version) -> str: package that cannot exist. """ if ver.major > 3: + # Backend-neutral: this also fires on the PlatformIO validation path + # (via _format_framework_arduino_version), where switching toolchains + # would not help raise EsphomeError( - f"Arduino core {ver} has no known package encoding; " - "use 'toolchain: platformio'" + f"Arduino core {ver} is not supported yet; " + "the newest known core series is 3.x" ) return f"3.{ver.major}{ver.minor:02d}{ver.patch:02d}.0" diff --git a/tests/unit_tests/test_arduino8266_framework.py b/tests/unit_tests/test_arduino8266_framework.py index 334f081bcb..c69f802c9e 100644 --- a/tests/unit_tests/test_arduino8266_framework.py +++ b/tests/unit_tests/test_arduino8266_framework.py @@ -25,10 +25,23 @@ def test_framework_package_version() -> None: # 2.6.3+ cores use the same package-major-3 encoding (PlatformIO path) assert framework.framework_package_version(cv.Version(2, 7, 4)) == "3.20704.0" # A future major bump needs its own encoding, not a doomed registry lookup - with pytest.raises(EsphomeError, match="no known package encoding"): + with pytest.raises(EsphomeError, match="not supported yet"): framework.framework_package_version(cv.Version(4, 0, 0)) +def test_format_framework_arduino_version_pins_all_series() -> None: + """The esp8266 component's PIO source formatter across every encoding + era, including the 4.x rejection it now shares with the installer.""" + from esphome.components.esp8266 import _format_framework_arduino_version as fmt + + assert fmt(cv.Version(2, 4, 1)) == "~1.20401.0" + assert fmt(cv.Version(2, 6, 2)) == "~2.20602.0" + assert fmt(cv.Version(2, 7, 4)) == "~3.20704.0" + assert fmt(cv.Version(3, 1, 2)) == "~3.30102.0" + with pytest.raises(EsphomeError, match="not supported yet"): + fmt(cv.Version(4, 0, 0)) + + def test_tools_path_default_and_prefix(tmp_path: Path) -> None: with patch.dict(os.environ, {"ESPHOME_ARDUINO8266_PREFIX": str(tmp_path)}): assert framework.get_arduino8266_tools_path() == tmp_path.resolve()