Merge branch 'esp8266-native-build-surgery' into esp8266-native-toolchain-plumbing

This commit is contained in:
J. Nick Koston
2026-08-20 20:48:32 -05:00
2 changed files with 52 additions and 9 deletions
+22 -6
View File
@@ -192,13 +192,17 @@ def run_extra_script(
pio_env=f"esphome_{board_mcu}",
pio_platform=pio_platform,
)
try:
source = script_path.read_text(encoding="utf-8")
except (OSError, UnicodeDecodeError) as err:
# An unreadable declared script is a broken package, exactly like a
# missing one; must not be quieter than that case
raise EsphomeError(f"extraScript {script_path} is unreadable: {err}") from err
old_cwd = Path.cwd()
try:
# Inside the try: a SyntaxError or bad encoding in a vendored script
# is just as best-effort as a runtime failure
code = compile(
script_path.read_text(encoding="utf-8"), str(script_path), "exec"
)
# Inside the try: a SyntaxError in a vendored script is just as
# best-effort as a runtime failure
code = compile(source, str(script_path), "exec")
os.chdir(library_dir)
exec( # noqa: S102 pylint: disable=exec-used
code,
@@ -209,7 +213,19 @@ def run_extra_script(
"__name__": "__pio_extra_script__",
},
)
except (SystemExit, Exception) as e: # noqa: BLE001 # pylint: disable=broad-exception-caught
except SystemExit as e:
if not e.code:
# sys.exit() / sys.exit(0) is a normal PlatformIO script ending;
# the capture is complete
return env.result
_LOGGER.warning(
"PIO extra-script %s (in %s) exited with status %r; ignoring its output",
script_path,
library_dir.name,
e.code,
)
return ExtraScriptResult()
except Exception as e: # noqa: BLE001 # pylint: disable=broad-exception-caught
# Discard any partial capture: folding half a script's flags into the
# build could produce wrong-output firmware that links cleanly. The
# warning plus the resulting loud link error point back here.
@@ -302,13 +302,40 @@ def test_unsupported_env_method_warns_once(caplog) -> None:
def test_run_extra_script_sys_exit_is_best_effort(tmp_path, caplog) -> None:
"""sys.exit() in a vendored script must not kill the esphome run."""
"""A nonzero sys.exit() in a vendored script must not kill the esphome
run, and its output is discarded."""
from esphome.platformio.extra_script import run_extra_script
script = tmp_path / "extra.py"
script.write_text("import sys\nsys.exit(3)\n")
script.write_text("import sys\nenv.Append(LIBS=['x'])\nsys.exit(3)\n")
result = run_extra_script(
script, library_dir=tmp_path, board_mcu="esp32", pio_platform="espressif32"
)
assert result.libs == []
assert "ignoring its output" in caplog.text
assert "exited with status 3" in caplog.text
def test_run_extra_script_sys_exit_zero_is_success(tmp_path, caplog) -> None:
"""sys.exit(0) is a normal PlatformIO script ending: the capture is kept."""
from esphome.platformio.extra_script import run_extra_script
script = tmp_path / "extra.py"
script.write_text("import sys\nenv.Append(LIBS=['algobsec'])\nsys.exit(0)\n")
result = run_extra_script(
script, library_dir=tmp_path, board_mcu="esp32", pio_platform="espressif32"
)
assert result.libs == ["algobsec"]
assert "ignoring its output" not in caplog.text
def test_run_extra_script_unreadable_raises(tmp_path) -> None:
"""An unreadable declared script is a broken package, like a missing one."""
from esphome.core import EsphomeError
from esphome.platformio.extra_script import run_extra_script
script = tmp_path / "extra.py"
script.write_bytes(b"\xff\xfe\x00bad")
with pytest.raises(EsphomeError, match="is unreadable"):
run_extra_script(
script, library_dir=tmp_path, board_mcu="esp32", pio_platform="espressif32"
)