Repository navigation
perf(collection): collect a parent level once for explicit file arguments - #15228
Open
ShahabAhmed01 wants to merge 1 commit into
Open
ShahabAhmed01 wants to merge 1 commit into
ShahabAhmed01 wants to merge 1 commit into
Conversation
…ents Explicit file arguments used to re-collect their parent level for every file argument: file arguments re-collect their level fresh, so N file arguments of one directory scanned that directory N times (and pruned all but one of the collected siblings each time), which scales with the number of file arguments times the number of their parent's entries. File argument paths that occur in more than one initial argument (--keepduplicates, or the same file selected with different :: parts) keep getting a fresh collection per occurrence, so directly given files are still not deduplicated. File arguments collected exactly once reuse the parent level's collection report instead, leaving node ids and their order unchanged. A cached failing report for such a level is still re-collected per file argument, as before, to keep collection failures reported as they were. Measured with the report's minimal reproduction (100 file arguments of a 150-entry directory, --collect-only, no caching plugin): 2.3-2.3s before, 0.4-0.4s after, equal to the directory-argument run. Collected items were equal before and after. Fixes pytest-dev#15221
There was a problem hiding this comment.
Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.
An organization owner can choose the repository organization as the billing source for reviews requested by members with a paid Copilot license. Learn about Copilot code review billing.
7 tasks done
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #15221
Summary
Explicit file arguments used to re-collect their parent level for every file argument: a file at the end of a path re-collects its level fresh (files given directly multiple times on the command line are not deduplicated), so
pytest a/test_1.py a/test_2.py … a/test_N.pyscanned the directory that holds the arguments once per argument and pruned all but one of the collected siblings each time.This collection now reuses the parent level's collection report for file arguments whose path occurs in exactly one initial argument, so the level is scanned once and the remaining arguments reuse it. Node ids and their order are unchanged.
The case where the same file path is given more than once keeps its previous behaviour: with
--keepduplicates, or when the same file is selected again with different::parts, each occurrence is still collected fresh per occurrence, so a directly given file is never deduplicated. A cached failing report for such a level is also still re-collected per file argument, so collection failures stay reported as before.Implementation
Session.perform_collectnow computes, once per collection, the set of file-argument paths that occur in more than one initial argument.Session.collectkeeps a fresh collection (handle_dupes=False) for those paths and reuses the level's cached report for file arguments collected exactly once.path_cacheonSession(used for the top-level arguments) and the per-level_collection_cachealready cover the rest of the walk, which is why directory arguments were unaffected by this slowdown.Testing
testing/test_collection.pygains four tests:test_file_arguments_scan_parent_level_onceasserts the parent level is scanned once for several explicit file arguments and that the node ids and order are unchanged.test_keepduplicates_runs_the_same_file_twiceasserts the same explicitly given file still collects twice with--keepduplicates.test_same_file_with_different_parts_is_collected_twiceasserts items selected with::parts from the same file are still collected per argument.test_file_arguments_recollect_after_failed_parent_collectionasserts a file argument whose parent level failed is re-collected per argument, matching the previous failure reporting.With the report's minimal reproduction (100 file arguments of a 150-entry directory,
--collect-only, one round each side,Python 3.14.8 / Linux):The collected items are identical before and after (the test asserts exact node id lists; the issue's own runs check 9,608 and 38,514 items).
Full results in this environment (Python 3.14.8, Linux):
tox -e py314is not run; the relevant test files pass in full:(
pre-commit.ciis green on this head; re-verified locally after opening:ruff checkandruff format --checkclean on the changed files with the pre-commit-pinnedruff0.17.1, andmypyclean onsrc/_pytest/main.py+testing/test_collection.pyunder the repo's own config — mypy 2.4.0, the pre-commit pin.)Scope
The change affects only the collection walk of explicit file arguments in
Session.collectand preserves the deduplication guarantees of files given directly multiple times on the command line. Directory arguments,::-part selections of now-reused levels,--pyargs,--keepduplicates, and the collection cache's Directory reconciliation from #14635 are untouched.Shahab Ahmed added to AUTHORS; changelog entry
changelog/15221.improvement.rstincluded.AI assistance disclosure
Per
CONTRIBUTING.rst's "AI/LLM-Assisted Contributions Policy": this change wasprepared with AI-assisted tooling as part of the author's contribution workflow —
the duplication sweep over existing issues/PRs, the reproduction and measurements,
the implementation iterations, and the test runs above. The author takes
responsibility for the diff, has reviewed it, and will engage with review feedback
from this account (never an automated reply loop). The commit carries no
Co-authored-bytrailer yet; if reviewers prefer one, I'll add it in a follow-upcommit rather than force-pushing this head.