From f301f54fcf2bdcd51f9529b5871afcd5b4080c15 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sat, 22 Aug 2026 23:33:26 -0500 Subject: [PATCH] Check the JSON shape explicitly instead of AttributeError control flow --- esphome/writer.py | 8 ++++---- tests/unit_tests/test_writer.py | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/esphome/writer.py b/esphome/writer.py index 6f061c53de..fbe36699e9 100644 --- a/esphome/writer.py +++ b/esphome/writer.py @@ -337,14 +337,14 @@ def copy_src_tree(): else: try: existing = json.loads(build_info_json_path.read_text(encoding="utf-8")) - if ( + if not isinstance(existing, dict) or ( existing.get("config_hash") != config_hash or existing.get("esphome_version") != __version__ ): + # Valid JSON that is not an object (truncated or + # hand-edited) is stale like every other damage case sources_changed = True - except (json.JSONDecodeError, AttributeError, KeyError, OSError): - # AttributeError: valid JSON that is not an object (truncated - # or hand-edited) has no .get; treat it as stale like the rest + except (json.JSONDecodeError, OSError): sources_changed = True # Write build_info header and JSON metadata diff --git a/tests/unit_tests/test_writer.py b/tests/unit_tests/test_writer.py index b0de99e039..37d999a816 100644 --- a/tests/unit_tests/test_writer.py +++ b/tests/unit_tests/test_writer.py @@ -2232,7 +2232,7 @@ def test_copy_src_tree_handles_non_dict_build_info_json( build_path = tmp_path / "build" build_path.mkdir() - # Create invalid build_info.json + # Valid JSON that is not an object: no .get, must read as stale build_info_json_path = build_path / "build_info.json" build_info_json_path.write_text("[]")