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
9.1.1: nested conftest fixtures are not found when file arguments interleave a nested directory with its parent #14971
Passing test files on the command line in the order nested/a.py parent/top.py nested/b.py makes fixtures defined in nested/conftest.py invisible to the last file on pytest 9.1.1. The same command passes on pytest 8.4.2, and passes on 9.1.1 when the two nested files are adjacent or when the directory is given instead of the files.
Minimal reproduction (Python 3.10.19, macOS, no plugins beyond the defaults):
What we traced (please treat as a pointer, not a diagnosis): with a bare file argument directly under an ancestor directory, Session.collect sets handle_dupes=False, so _collect_one_node bypasses its cache and re-collects tests/services, producing a second Directory node instance for the same path. Since 9.x matches fixture visibility by node identity in FixtureManager._matchfactories rather than by nodeid prefix, fixtures registered on the first tests/services instance are invisible to items collected under the second one. Two real projects hit this from developers running a hand-picked file list; pytest tests/ is unaffected.
Trace confirms the pointer: Session.collect passes handle_dupes=False for bare file args, so _collect_one_node re-collects tests/services and creates a second Directory node for the same path. FixtureManager._matchfactories then matches by node identity (nodeid equality of the collected parent chain), so fixtures defined in nested/conftest.py and registered under the first Directory instance are invisible to items collected under the second one.
Plan:
Regression test from the minimal repro (interleaved file args: nested/a.py parent/top.py nested/b.py).
Fix in collection — either make the handle_dupes=False path reuse the existing cached Directory node when it already exists, or match fixtures by nodeid prefix in _matchfactories instead of node identity.
I'll follow the contributor guidelines and aim to keep the diff minimal.
Update after verification — retracting my claim, this is already fixed on main.
Verified on a clean venv: the repro fails on 9.1.1 exactly as reported (2 passed, 1 error, fixture lost on the interleaved run), but passes 3/3 on current main (built from source).
The fix is #14635 (commit fc8f56bd2, merged 2026-07-22): _collect_one_node now reconciles re-collected Directory children with cached ones so fixture registration keyed by node identity stays valid — precisely the mechanism traced in this report. It landed after the 9.1.1 release (2026-06-19), which is why the reporter still sees it; there is no 9.1.x maintenance branch, so it ships with 9.2.0.
Sorry for the noise on the claim — hope the verification still saves a triage round. Thanks for the excellent root-cause tracing, it made this a five-minute check.
Activity
test: every fixture lives in the root conftests and a gate test fails…
kokhlo commentedon Sep 7, 2026
Hi! I can take this one.
Trace confirms the pointer:
Session.collectpasseshandle_dupes=Falsefor bare file args, so_collect_one_nodere-collectstests/servicesand creates a secondDirectorynode for the same path.FixtureManager._matchfactoriesthen matches by node identity (nodeid equality of the collected parent chain), so fixtures defined innested/conftest.pyand registered under the firstDirectoryinstance are invisible to items collected under the second one.Plan:
nested/a.py parent/top.py nested/b.py).handle_dupes=Falsepath reuse the existing cachedDirectorynode when it already exists, or match fixtures by nodeid prefix in_matchfactoriesinstead of node identity.I'll follow the contributor guidelines and aim to keep the diff minimal.
kokhlo commentedon Sep 7, 2026
Update after verification — retracting my claim, this is already fixed on main.
Verified on a clean venv: the repro fails on 9.1.1 exactly as reported (
2 passed, 1 error, fixture lost on the interleaved run), but passes 3/3 on current main (built from source).The fix is #14635 (commit
fc8f56bd2, merged 2026-07-22):_collect_one_nodenow reconciles re-collected Directory children with cached ones so fixture registration keyed by node identity stays valid — precisely the mechanism traced in this report. It landed after the 9.1.1 release (2026-06-19), which is why the reporter still sees it; there is no 9.1.x maintenance branch, so it ships with 9.2.0.Sorry for the noise on the claim — hope the verification still saves a triage round. Thanks for the excellent root-cause tracing, it made this a five-minute check.
RonnyPfannschmidt commentedon Sep 11, 2026
#14968 is the backport
rennf93 commentedon Sep 11, 2026
Tyvm @RonnyPfannschmidt @kokhlo !
fix(tests): register web_admin fixtures from the root conftest so int…
test: the interleaved-args probe runs unconditionally instead of skip…
fix(tests): port pytest's Directory re-collection fix — conftest fixt…
Weigh the words of the costliest coset queries by their pivot-deleted…