From 7a659973e362673d130e33f51b2a4332644b8260 Mon Sep 17 00:00:00 2001 From: "devin-ai-integration[bot]" <158243242+devin-ai-integration[bot]@users.noreply.github.com> Date: Thu, 8 Oct 2026 08:40:08 +0000 Subject: [PATCH] revert(lint-gates): accept an empty base scan again, since zero violations is a legitimate count (#45319) This reverts commit 7c7efd4d55b331ea2c6f688ca1ca4db727fc1b69 (#45314). Co-authored-by: mateo-berri <277851410+mateo-berri@users.noreply.github.com> --- scripts/lint_base_counts.py | 15 ++++----------- scripts/type_check_gate.py | 10 +++++++++- tests/unit/test_lint_base_counts.py | 19 ++++++++++--------- 3 files changed, 23 insertions(+), 21 deletions(-) diff --git a/scripts/lint_base_counts.py b/scripts/lint_base_counts.py index b710ac0ae1b..2b86d4ce55b 100644 --- a/scripts/lint_base_counts.py +++ b/scripts/lint_base_counts.py @@ -276,9 +276,8 @@ def base_counts_cached( ) -> Counts: """`compute` memoized on disk. The base tree at a given commit is immutable, so its counts are a pure function of the merge-base plus the checker's - fingerprints in the cache key. An empty local result fails the gate instead of - being returned, because it is the signature of a crashed pass, not a clean - tree, and would make every existing violation look new. On a disk miss the counts + fingerprints in the cache key; an empty result is never stored because it is + the signature of a crashed pass, not a clean tree. On a disk miss the counts CI already published for the merge-base are fetched before the expensive local base scan; a fetch miss of any kind computes locally.""" directory: Final = default_cache_dir() if cache_dir is None else cache_dir @@ -290,14 +289,8 @@ def base_counts_cached( store_counts(directory, checker, base_point, fetched) return fetched counts: Final = compute(base_point) - if not counts: - print( - f"FAIL: {checker.name} produced no violations for the base tree at {base_point[:12]}, " - "so every rule would look freshly added. The base pass almost certainly " - "crashed; refusing to blame this change for it." - ) - raise SystemExit(1) - store_counts(directory, checker, base_point, counts) + if counts: + store_counts(directory, checker, base_point, counts) return counts diff --git a/scripts/type_check_gate.py b/scripts/type_check_gate.py index dbcce091ac6..2a9f1c1229f 100644 --- a/scripts/type_check_gate.py +++ b/scripts/type_check_gate.py @@ -279,7 +279,15 @@ def cmd_check(head: Mapping[str, int], base_ref: str) -> None: ) raise SystemExit(1) base_point: Final = resolve_base_point(base_ref) - judge(head, base_counts_cached(checker_identity(), base_point, base_counts), base_point) + base: Final = base_counts_cached(checker_identity(), base_point, base_counts) + if not base: + print( + f"FAIL: basedpyright produced no errors for the base tree at {base_point[:12]}, " + "so every rule would look freshly added. The base pass almost certainly " + "crashed; refusing to blame this change for it." + ) + raise SystemExit(1) + judge(head, base, base_point) def judge(head: Mapping[str, int], base: Mapping[str, int], base_point: str) -> None: diff --git a/tests/unit/test_lint_base_counts.py b/tests/unit/test_lint_base_counts.py index 29fa57a6b4b..84f8a0936c0 100644 --- a/tests/unit/test_lint_base_counts.py +++ b/tests/unit/test_lint_base_counts.py @@ -203,15 +203,16 @@ def test_base_counts_cached_keeps_each_checker_apart(tmp_path: Path) -> None: ) == {"reportAny": 4} -def test_an_empty_base_pass_fails_the_gate_instead_of_blaming_the_change( - tmp_path: Path, capsys: pytest.CaptureFixture[str] -) -> None: - with pytest.raises(SystemExit) as exit_info: - counts.base_counts_cached( - _CHECKER, "abc123def4567", lambda ref: {}, cache_dir=tmp_path, fetch=lambda checker, base_point: {} - ) - assert exit_info.value.code == 1 - assert f"FAIL: {_CHECKER.name} produced no violations for the base tree at abc123def456," in capsys.readouterr().out +def test_an_empty_base_pass_is_never_cached(tmp_path: Path) -> None: + calls: Final[list[str]] = [] + + def crashed(ref: str) -> counts.Counts: + calls.append(ref) + return {} + + assert counts.base_counts_cached(_CHECKER, "abc123", crashed, cache_dir=tmp_path, fetch=_no_fetch) == {} + assert counts.base_counts_cached(_CHECKER, "abc123", crashed, cache_dir=tmp_path, fetch=_no_fetch) == {} + assert calls == ["abc123", "abc123"] assert list(tmp_path.iterdir()) == []