test(drift): flag unreachable statements and raise the call-argument floor (t62 F2)
Two gate gaps let the t62 findings ship, and both are closed here. A pure-AST unreachable-statement pass (scan(): pass 6, entry point scan_unreachable()): in every statement block, a statement after return/raise/continue/break can never run. Per-block on purpose — an `else`, an except handler or a nested function is a different block and not dead, so the pass stays signal. Red proof: the pre-fix connection.py, saved from HEAD, is flagged as `connection.py:1113: unreachable-statement: return at line 1110 ends this block`; the live tree is clean. A new counter (statement_blocks, floor 500 of ~1102) keeps the "no findings" verdict from being a pass that stopped parsing. The call-argument floor was 20 while the walk counted 46, so deleting a flow-display owner from HA_CALL_OWNERS did not trip it. It is 44 now, and the suite proves the trip: removing async_show_menu yields 40 checked arguments and `only 40 call_args (floor: 44)`. Measured removals: show_form 25, abort 38, show_menu 40, create_entry 41, update_entry 41 all violate; the single-call-site async_update_reload_and_abort (45) is the one owner a count floor cannot watch, which is why the floor sits two below the count. Also (t62 nit a): the two comments that pinned the t40 entity-attribute finding to ``media_player.py:828`` now name the file and the attribute instead — the line had rotted to an unrelated property.
This commit is contained in:
1 parent
0ef72a1fbb
commit
93d0afcdcf
2 files changed
+203
-12
No files matched your search
@@ -381,3 +381,102 @@ def test_the_real_ha_matrix_covers_every_entity_class_in_the_tree():
|
||||
f"entity classes never exercised against real HA: {sorted(uncovered)} — "
|
||||
f"add them to _REAL_HA_MATRIX"
|
||||
)
|
||||
|
||||
|
||||
# ------------------------------------------------- t62: dead code and the floor
|
||||
#
|
||||
# Both defects pinned below shipped while every other gate was green:
|
||||
# connection.py carried a duplicated copy of the label-drain body AFTER its
|
||||
# `return cached` (valid Python, dead, invisible to this sweep), and the
|
||||
# call-argument floor sat at 20 while the counts had moved to ~46, so deleting a
|
||||
# flow-display API owner from HA_CALL_OWNERS did not trip it.
|
||||
|
||||
#: t62 F2: the shape that shipped — a bare docstring plus the whole drain left
|
||||
#: after `return cached`, inside the same method. Line 6 is the dead statement.
|
||||
UNREACHABLE_PRE_FIX = (
|
||||
"class Sweep:\n"
|
||||
" def labels(self, requests):\n"
|
||||
" cached = {}\n"
|
||||
" return cached\n"
|
||||
"\n"
|
||||
' """Start at most one label fetch per watchdog cycle."""\n'
|
||||
" if not requests:\n"
|
||||
" return\n"
|
||||
" requests.discard(min(requests))\n"
|
||||
)
|
||||
|
||||
|
||||
def test_the_sweep_flags_the_pre_fix_unreachable_body(tmp_path):
|
||||
"""t62 F2 red proof: the duplicated drain body after `return cached` is dead."""
|
||||
(tmp_path / "dead_sweep.py").write_text(UNREACHABLE_PRE_FIX, encoding="utf-8")
|
||||
|
||||
findings = ha_api_drift.scan_unreachable(tmp_path)
|
||||
|
||||
assert [(finding.path, finding.kind) for finding in findings] == [
|
||||
("dead_sweep.py", "unreachable-statement")
|
||||
], findings
|
||||
assert findings[0].lineno == 6 # the dead docstring, not the return
|
||||
|
||||
|
||||
def test_every_terminal_statement_kind_is_flagged(tmp_path):
|
||||
"""`return`, `raise`, `continue` and `break` all end a block (t62 F2)."""
|
||||
(tmp_path / "terminals.py").write_text(
|
||||
"def a():\n"
|
||||
" return 1\n"
|
||||
" x = 1\n"
|
||||
"\n"
|
||||
"\n"
|
||||
"def b():\n"
|
||||
" raise SystemExit(1)\n"
|
||||
" y = 2\n"
|
||||
"\n"
|
||||
"\n"
|
||||
"def c(items):\n"
|
||||
" for item in items:\n"
|
||||
" continue\n"
|
||||
" z = 3\n"
|
||||
" while True:\n"
|
||||
" break\n"
|
||||
" w = 4\n",
|
||||
encoding="utf-8",
|
||||
)
|
||||
|
||||
findings = ha_api_drift.scan_unreachable(tmp_path)
|
||||
|
||||
assert [finding.kind for finding in findings] == ["unreachable-statement"] * 4, findings
|
||||
|
||||
|
||||
def test_the_production_tree_has_no_unreachable_statements():
|
||||
"""The gate itself: dead code is a finding, so it cannot ship silently."""
|
||||
assert ha_api_drift.scan_unreachable() == []
|
||||
|
||||
|
||||
def test_the_unreachable_pass_walks_real_statement_blocks():
|
||||
"""The floor proves "no findings" is not a pass that stopped parsing."""
|
||||
report = ha_api_drift.scan()
|
||||
|
||||
assert report.statement_blocks >= ha_api_drift.FLOORS["statement_blocks"]
|
||||
|
||||
|
||||
def test_removing_a_flow_display_owner_trips_the_call_argument_floor(monkeypatch):
|
||||
"""t62: the floor must notice an API OWNER going away, not just a bad walk."""
|
||||
_require_installed_homeassistant()
|
||||
|
||||
intact = ha_api_drift.scan()
|
||||
assert intact.floor_violations() == []
|
||||
|
||||
reduced = dict(ha_api_drift.HA_CALL_OWNERS)
|
||||
del reduced["async_show_menu"] # the t57 UNIT 0a owner: 6 checked arguments
|
||||
monkeypatch.setattr(ha_api_drift, "HA_CALL_OWNERS", reduced)
|
||||
|
||||
fewer = ha_api_drift.scan()
|
||||
|
||||
assert fewer.call_args < intact.call_args
|
||||
assert fewer.call_args < ha_api_drift.FLOORS["call_args"], (
|
||||
f"removing async_show_menu left {fewer.call_args} checked arguments, "
|
||||
f"still at or above the floor of {ha_api_drift.FLOORS['call_args']} — "
|
||||
"the flow-display owners are not load-bearing"
|
||||
)
|
||||
assert any("call_args" in line for line in fewer.floor_violations()), (
|
||||
fewer.floor_violations()
|
||||
)
|
||||
Reference in new issue
Block a user