From 024e0aef286a717d1c2577a18df408ae7f153b6e Mon Sep 17 00:00:00 2001 From: Arjun Sharma Date: Wed, 30 Sep 2026 20:35:04 +0000 Subject: [PATCH] lightspeed: record only files a benchmark's timed body executes as its deps --- asv/contrib/lightspeed/survey.py | 8 +------ test/test_lightspeed_survey.py | 39 ++++++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+), 7 deletions(-) create mode 100644 test/test_lightspeed_survey.py diff --git a/asv/contrib/lightspeed/survey.py b/asv/contrib/lightspeed/survey.py index 5199469d..1ed611f9 100644 --- a/asv/contrib/lightspeed/survey.py +++ b/asv/contrib/lightspeed/survey.py @@ -205,13 +205,7 @@ def survey_one( lines: Set[int] = set(cov_data.lines(fname) or []) if not lines: - # File was measured but no line-level data — use whole-file - # fingerprint so changes to it still trigger re-runs. - fp, sha = file_method_checksums(fname) - if sha is not None: - file_deps[fname] = (fp, sha) - elif uncomputable is None: - uncomputable = fname + # With source=, coverage also lists files that never ran; they are not deps of this benchmark. continue fp, sha = coverage_fingerprint(fname, lines) diff --git a/test/test_lightspeed_survey.py b/test/test_lightspeed_survey.py new file mode 100644 index 00000000..94a87ea4 --- /dev/null +++ b/test/test_lightspeed_survey.py @@ -0,0 +1,39 @@ +"""survey_one records only the source files a benchmark's timed body executes.""" + +import sys +import textwrap + +import pytest + +pytest.importorskip("coverage") +from asv.contrib.lightspeed.deps_db import BenchmarkId # noqa: E402 +from asv.contrib.lightspeed.survey import survey_one # noqa: E402 + + +@pytest.fixture +def project(tmp_path, monkeypatch): + pkg = tmp_path / "pkg" + pkg.mkdir() + (pkg / "__init__.py").write_text("") + (pkg / "used.py").write_text("def work(n):\n return sum(range(n))\n") + (pkg / "unused.py").write_text("def idle():\n return 0\n") + bench = tmp_path / "benchmarks" + bench.mkdir() + (bench / "__init__.py").write_text("") + (bench / "bench_pkg.py").write_text(textwrap.dedent(""" + import pkg.unused + from pkg.used import work + + def time_work(): + work(1000) + """)) + monkeypatch.syspath_prepend(str(tmp_path)) + yield tmp_path + for name in [m for m in sys.modules if m == "pkg" or m.startswith(("pkg.", "bench_pkg"))]: + del sys.modules[name] + + +def test_only_executed_files_are_deps(project): + ok, reason, deps = survey_one(str(project / "benchmarks"), BenchmarkId("bench_pkg.time_work"), str(project / "pkg")) + assert ok, reason + assert {p.split("/pkg/")[-1] for p in deps} == {"used.py"}