You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
A terminal file argument re-collects its parent package and forks subpackage collectors, losing conftest fixtures (9.1.x) #15071
Any order where a sub-package file argument sits between two top-level file arguments triggers it.
Mechanism (from reading 9.1.1 source and instrumenting)
Session.collect builds each file argument's parent chain. For a terminal file part it calls _collect_one_node(parent, handle_dupes=False) — the collection cache is bypassed for the file's parent, so duplicate file arguments keep working.
That re-collection runs Package.collect() again for the parent (tests), which has no per-path dedup: it creates a freshPackage collector for every subpackage (tests/sub) via pytest_collect_directory, and _collect_one_node stores the fresh report, replacing the cached children.
Conftest fixtures are bound one-shot: FixtureManager.pytest_make_collect_report pops _pending_conftests for the directory path at the first Directory report, binding the fixturedefs to that first collector object.
Items collected under a later duplicate Package then fail FixtureManager._matchfactories, which in 9.1.x matches by node identity first (fixturedef.node in parent_nodes) — the string-baseid fallback never runs because fixturedef.node is not None — producing "fixture not found" for exactly those items.
Instrumentation on a large real suite (one session, ~200 file arguments) counted 7 distinct Package objects for one directory and systematic "fixture not found" errors for the items under the later copies. Absolute vs relative file arguments make no difference (arguments are absolutized internally), and 9.1.1 shows the same behavior as 9.1.0.
Expected behavior
One collector object per directory path per session, so conftest fixturedefs remain visible to every item collected under that directory regardless of argument order.
Workaround in use
A firstresult pytest_collect_directory hook that returns the already-created collector for a path (recorded at pytest_collectstart) prevents the fork.
Duplicate of #14635, already fixed and waiting on a release. Closing.
Written by Claude Opus 5 via Claude Code for the issue reporter; I prompted it, it did the work, I read it.
The fix is #14645 (fc8f56bd2, "fix: deduplicate Directory nodes on re-collection to preserve fixture identity"), backported to 9.1.x in #14968. It makes one collector object per directory path per session.
No released version carries it yet — 9.1.1 predates the merge, which is why the 9.1.1 source matches your analysis. The reproducer in this issue passes unmodified on current main and 9.1.x. Until 9.1.2, the pytest_collect_directory hook or sorting the file arguments both avoid it.
Activity
RonnyPfannschmidt commentedon Sep 21, 2026
Duplicate of #14635, already fixed and waiting on a release. Closing.
Written by Claude Opus 5 via Claude Code for the issue reporter; I prompted it, it did the work, I read it.
The fix is #14645 (
fc8f56bd2, "fix: deduplicate Directory nodes on re-collection to preserve fixture identity"), backported to9.1.xin #14968. It makes one collector object per directory path per session.No released version carries it yet — 9.1.1 predates the merge, which is why the 9.1.1 source matches your analysis. The reproducer in this issue passes unmodified on current
mainand9.1.x. Until 9.1.2, thepytest_collect_directoryhook or sorting the file arguments both avoid it.