From 14388c859aeb29b92a12f6b1272866d531cfb988 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sun, 23 Aug 2026 16:09:26 -0500 Subject: [PATCH] Mirror the backstop-ownership trim from the standalone --- esphome/espidf/size_summary.py | 17 +++++------------ tests/unit_tests/test_size_summary.py | 15 +++++++-------- 2 files changed, 12 insertions(+), 20 deletions(-) diff --git a/esphome/espidf/size_summary.py b/esphome/espidf/size_summary.py index 77e650da7d..d860024b9c 100644 --- a/esphome/espidf/size_summary.py +++ b/esphome/espidf/size_summary.py @@ -52,13 +52,11 @@ def _find_app_partition_size(partitions_csv: Path) -> int | None: whose subtype is ``factory`` or ``ota_0``. Order matters because layouts like Adafruit's ``partitions-4MB-tinyuf2.csv`` repurpose ``factory`` for a UF2 bootloader before the real OTA slot, so a - naive "prefer factory" rule would pick the wrong row. A missing - table or no qualifying row is legitimate absence (None); malformed - tables cannot reach a successful build (gen_esp32part rejects them), - so parse failures go to the caller's backstop. + naive "prefer factory" rule would pick the wrong row. No qualifying + row is legitimate absence (None); a build cannot succeed with a + missing or malformed table (gen_esp32part consumes it first), so + those states belong to the backstop. """ - if not partitions_csv.is_file(): - return None for row in csv.reader(partitions_csv.read_text(encoding="utf-8").splitlines()): cells = [c.strip() for c in row] if not cells or cells[0].startswith("#") or len(cells) < 5: @@ -159,12 +157,7 @@ def _flash_bar( if partitions_csv is None: _LOGGER.debug("Skipping Flash summary: no partition table given") return None - try: - app_size = _find_app_partition_size(partitions_csv) - except OSError as e: - # A read race on a table the build just used; visible but non-fatal - _LOGGER.warning("Skipping Flash summary: %s", e) - return None + app_size = _find_app_partition_size(partitions_csv) if not app_size: # No table or no qualifying row: legitimate for non-app layouts _LOGGER.debug("Skipping Flash summary: no app partition in %s", partitions_csv) diff --git a/tests/unit_tests/test_size_summary.py b/tests/unit_tests/test_size_summary.py index e1bdf56ddc..5aa3bb1fee 100644 --- a/tests/unit_tests/test_size_summary.py +++ b/tests/unit_tests/test_size_summary.py @@ -156,7 +156,7 @@ def test_print_summary_non_dict_json_is_skipped( def test_print_summary_unreadable_partitions_is_skipped( - tmp_path: Path, capsys: pytest.CaptureFixture[str] + tmp_path: Path, capsys: pytest.CaptureFixture[str], caplog: pytest.LogCaptureFixture ) -> None: """An OSError reading the partition table skips the summary, not the build.""" size_json = _write_size_json(tmp_path, _dram_size_data()) @@ -170,8 +170,10 @@ def test_print_summary_unreadable_partitions_is_skipped( with patch.object(Path, "read_text", fail_partitions_read): print_summary(size_json, partitions) + # An impossible post-build state is the backstop's business out = capsys.readouterr().out assert "RAM:" in out and "Flash:" not in out + assert "Skipping size summary for" in caplog.text def test_print_summary_happy_path_prints_both_bars( @@ -279,19 +281,16 @@ def test_print_summary_missing_or_appless_partitions_stay_quiet( capsys: pytest.CaptureFixture[str], caplog: pytest.LogCaptureFixture, ) -> None: - """A missing table or one without a qualifying app row is a legitimate - layout: the Flash line drops at debug, never at warning.""" + """A table without a qualifying app row is a legitimate layout: the + Flash line drops at debug, never at warning.""" size_json = _write_size_json(tmp_path, _dram_size_data()) + partitions = _write_partitions(tmp_path, "0x1000", ptype="data", subtype="spiffs") with caplog.at_level(logging.DEBUG, logger="esphome.espidf.size_summary"): - print_summary(size_json, tmp_path / "nope.csv") - partitions = _write_partitions( - tmp_path, "0x1000", ptype="data", subtype="spiffs" - ) print_summary(size_json, partitions) out = capsys.readouterr().out assert "Flash:" not in out # Quiet means debug-logged, not unlogged - assert caplog.text.count("Skipping Flash summary: no app partition") == 2 + assert "Skipping Flash summary: no app partition" in caplog.text assert not [r for r in caplog.records if r.levelno >= logging.WARNING]