From 7aa0f30ceb29af8ca51d756bb0d44422e1004b50 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sun, 23 Aug 2026 16:06:38 -0500 Subject: [PATCH] Mirror the unreachable-arm removal from the standalone --- esphome/espidf/size_summary.py | 28 +++++-------------- tests/unit_tests/test_size_summary.py | 39 +++++---------------------- 2 files changed, 13 insertions(+), 54 deletions(-) diff --git a/esphome/espidf/size_summary.py b/esphome/espidf/size_summary.py index ca3fbf94bd..77e650da7d 100644 --- a/esphome/espidf/size_summary.py +++ b/esphome/espidf/size_summary.py @@ -36,8 +36,6 @@ _SIZE_SUFFIXES = {"K": 1024, "M": 1024 * 1024} def _parse_size(token: str) -> int: token = token.strip() - if not token: - raise ValueError("blank partition size cell") if token.startswith(("0x", "0X")): return int(token, 16) suffix = token[-1].upper() @@ -55,8 +53,9 @@ def _find_app_partition_size(partitions_csv: Path) -> int | None: 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); a raise - always means a present-but-broken table. + 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. """ if not partitions_csv.is_file(): return None @@ -66,12 +65,7 @@ def _find_app_partition_size(partitions_csv: Path) -> int | None: continue ptype, psubtype, psize = cells[1], cells[2], cells[4] if ptype in ("app", "0") and psubtype in ("factory", "ota_0"): - try: - return _parse_size(psize) - except ValueError as err: - raise ValueError( - f"{err} for partition {cells[0]} in {partitions_csv}" - ) from err + return _parse_size(psize) return None @@ -167,20 +161,12 @@ def _flash_bar( return None try: app_size = _find_app_partition_size(partitions_csv) - except (ValueError, OSError, csv.Error) as e: - # The table is there but broken/unreadable: visible, like size 0 + 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 - if app_size is None: + 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) return None - if app_size <= 0: - # Skipping also fails CI's Flash extraction, the right outcome here - _LOGGER.warning( - "Skipping Flash summary: app partition size is %s in %s", - app_size, - partitions_csv, - ) - return None return int(image_size), app_size diff --git a/tests/unit_tests/test_size_summary.py b/tests/unit_tests/test_size_summary.py index 5345c3b9f3..e1bdf56ddc 100644 --- a/tests/unit_tests/test_size_summary.py +++ b/tests/unit_tests/test_size_summary.py @@ -174,17 +174,6 @@ def test_print_summary_unreadable_partitions_is_skipped( assert "RAM:" in out and "Flash:" not in out -def test_print_summary_zero_app_partition_is_skipped( - tmp_path: Path, capsys: pytest.CaptureFixture[str] -) -> None: - """A 0-size app partition drops the Flash bar instead of rendering 0%.""" - size_json = _write_size_json(tmp_path, _dram_size_data()) - partitions = _write_partitions(tmp_path, "0") - print_summary(size_json, partitions) - out = capsys.readouterr().out - assert "RAM:" in out and "Flash:" not in out - - def test_print_summary_happy_path_prints_both_bars( tmp_path: Path, capsys: pytest.CaptureFixture[str] ) -> None: @@ -271,32 +260,16 @@ def test_print_summary_blanket_guard_catches_the_rest( assert "Skipping size summary for" in caplog.text -@pytest.mark.parametrize("cell", ["", "1.5M", "abc"], ids=["blank", "float", "junk"]) -def test_print_summary_blank_size_cell_names_the_row( - tmp_path: Path, - capsys: pytest.CaptureFixture[str], - caplog: pytest.LogCaptureFixture, - cell: str, -) -> None: - """An unparseable size cell raises ValueError instead of parsing to 0.""" - size_json = _write_size_json(tmp_path, _dram_size_data()) - partitions = _write_partitions(tmp_path, cell) - print_summary(size_json, partitions) - out = capsys.readouterr().out - assert "RAM:" in out and "Flash:" not in out - # Pins the ValueError path: pre-diff, "" parsed to 0 and the size-0 - # warning fired instead - assert "Skipping Flash summary" in caplog.text - assert "app0" in caplog.text and str(partitions) in caplog.text - - +@pytest.mark.parametrize("cell", ["1M", "1048576"], ids=["suffixed", "decimal"]) def test_print_summary_suffixed_size_cell( - tmp_path: Path, capsys: pytest.CaptureFixture[str] + tmp_path: Path, capsys: pytest.CaptureFixture[str], cell: str ) -> None: - """K/M suffixes parse like PlatformIO's rule (1M = 1048576 bytes).""" + """K/M suffixes and plain decimals parse like PlatformIO's rule.""" size_json = _write_size_json(tmp_path, _dram_size_data()) partitions = tmp_path / "partitions.csv" - partitions.write_text("# comment row\nshort,row\napp0, app, ota_0, 0x10000, 1M,\n") + partitions.write_text( + f"# comment row\nshort,row\napp0, app, ota_0, 0x10000, {cell},\n" + ) print_summary(size_json, partitions) assert "from 1048576 bytes" in capsys.readouterr().out