diff --git a/src/openultrasast/hunt/producers.py b/src/openultrasast/hunt/producers.py index 63c5afc..1899a02 100644 --- a/src/openultrasast/hunt/producers.py +++ b/src/openultrasast/hunt/producers.py @@ -91,7 +91,13 @@ class Context: @cached_property def entry_points(self) -> list[mapping.EntryPointRecord]: for path in self.product_files: - self.read(path) + try: + self.read(path) + except _Absent: + # An empty product file elsewhere in the tree is not this row's problem. Before this guard one + # such file failed the source producer on every row of the change, and the failure escaped the + # cache so every row re-read the whole tree. + continue return mapping.analyze_entry_points(self.root, [build_file_target(self.root, self.root / path) for path in self.product_files]) @cached_property diff --git a/tests/test_hunt_producers.py b/tests/test_hunt_producers.py index 55cd523..4b20d1f 100644 --- a/tests/test_hunt_producers.py +++ b/tests/test_hunt_producers.py @@ -181,7 +181,8 @@ def test_a_removed_guard_anchors_the_function_it_left(tmp_path): check = " if not user.is_admin:\n raise PermissionError\n" guarded = "def first():\n return 1\n\n\ndef admin(user):\n" + check + " return delete_everything()\n" (tmp_path / "app.py").write_text(guarded) - git("add", "app.py") + (tmp_path / "empty.py").write_text("") # an empty product file elsewhere must not fail the row's producers + git("add", "app.py", "empty.py") git("commit", "-qm", "fix: require admin") base = git("rev-parse", "HEAD") (tmp_path / "app.py").write_text(guarded.replace(check, "")) @@ -191,6 +192,7 @@ def test_a_removed_guard_anchors_the_function_it_left(tmp_path): change = {"id": "c", "case_id": "c-1", "repo": "fixture/repo", "base": base, "head": head, "kind": "ordinary", "fold": 1, "files": [{"path": "app.py", "head_lines": [[1, 1], [5, 6]]}]} # fmt: skip rows = compute_rows(tmp_path, change) + assert all(r["provenance.source.ok"] for r in rows), [r["provenance.source.reason"] for r in rows] row = next(r for r in rows if r["feature.source.function"] == "admin") assert row["feature.diff.hunks"] == [] and row["feature.diff.deletions"] == [5] assert row["feature.diff.on_changed_line"] and row["feature.diff.distance"] == 0