From 791020f77828a549072bc1b1ffd69ab8078d2412 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Tue, 25 Aug 2026 20:00:27 -0500 Subject: [PATCH] Merge follow-through: discard the pch when its identity cannot be established --- esphome/build_helpers/pch.py | 28 +++++++++++++++-------- tests/unit_tests/build_gen/test_espidf.py | 21 +++++++++++++++++ 2 files changed, 39 insertions(+), 10 deletions(-) diff --git a/esphome/build_helpers/pch.py b/esphome/build_helpers/pch.py index bc594d496e..21e49598ef 100644 --- a/esphome/build_helpers/pch.py +++ b/esphome/build_helpers/pch.py @@ -294,16 +294,24 @@ def prepare_pch( .replace(effective_ccache_basedir(), "") .replace(str(CORE.build_path), "") ) - checksum = pch_checksum( - CORE.relative_src_path(), - include_headers, - ( - # The closure is sorted, so root order only enters via the text - pch_header_text(include_headers), - *extra, - cmd_id, - ), - ) + try: + checksum = pch_checksum( + CORE.relative_src_path(), + include_headers, + ( + # The closure is sorted, so root order only enters via the text + pch_header_text(include_headers), + *extra, + cmd_id, + ), + ) + except OSError as err: + # Identity unknown: a stale cache entry must never be served + _LOGGER.warning( + "Could not establish the pch identity; compiling without it: %s", err + ) + discard_pch(build_dir) + return if ( gch.is_file() and sum_path.is_file() diff --git a/tests/unit_tests/build_gen/test_espidf.py b/tests/unit_tests/build_gen/test_espidf.py index 62fee5f8ad..6c62baa6f0 100644 --- a/tests/unit_tests/build_gen/test_espidf.py +++ b/tests/unit_tests/build_gen/test_espidf.py @@ -1005,3 +1005,24 @@ def test_prepare_pch_keeps_user_force_includes(tmp_path: Path) -> None: cmd, _ = pch_compile_command(build, build / "esphome_pch.h", build / "x.gch") assert "user.h" in cmd assert "esphome_pch.h" not in " ".join(cmd[:-3]) + + +def test_prepare_pch_identity_unknown_discards(tmp_path: Path) -> None: + """An OSError from the checksum discards artifacts and skips the pch.""" + from esphome.build_gen.espidf import prepare_pch + + dev = _make_pch_device(tmp_path, "dev_i") + CORE.build_path = dev + stale = dev / "build" / "esphome_pch.h.gch" + stale.write_bytes(b"stale") + with ( + patch.object(CORE, "name", "test"), + patch( + "esphome.build_helpers.pch.pch_checksum", + side_effect=OSError("stat failed"), + ), + patch("esphome.build_helpers.pch.subprocess.run", side_effect=AssertionError), + ): + prepare_pch() + assert not stale.exists() + assert not (dev / "build" / "esphome_pch.h.gch.sum").exists()