Skip to content

Fix rootdir conftest fixtures not visible to items collected outside the rootdir#14694

Open
breidenbach0 wants to merge 1 commit into
pytest-dev:mainfrom
breidenbach0:fix/doctest-namespace-not-loaded-outside-rootdir
Open

Fix rootdir conftest fixtures not visible to items collected outside the rootdir#14694
breidenbach0 wants to merge 1 commit into
pytest-dev:mainfrom
breidenbach0:fix/doctest-namespace-not-loaded-outside-rootdir

Conversation

@breidenbach0

Copy link
Copy Markdown

Problem

Fixes #14683.

doctest_namespace injections (and any fixture defined in the rootdir conftest) stopped being available in pytest 9.1 when --rootdir points to a subdirectory and tests/doctests are collected from a parent directory. Doctests then fail with NameError, e.g. the reporter's invocation:

pytest --rootdir src/xclim/testing --config-file=src/xclim/testing/conftest.py \
       --doctest-modules src/xclim

Reproduced: 9.0.3 passes, 9.1.1 fails with NameError: name '...' is not defined.

Cause

Bisected to 46478fad5 (#14098, pytest 9.1), which changed conftest fixture visibility from nodeid-based to node-based:

  • Before 9.1: a conftest located in the rootdir got an empty baseid (relative to rootdir), which matches every collected item — its fixtures were visible session-wide.
  • After 9.1: that conftest is scoped to its own Directory node. When items are collected from outside the rootdir, that Directory is a sibling subtree, not an ancestor of the items, so the fixtures are no longer visible.

Fix

Restore the pre-9.1 behavior by attaching the rootdir conftest to the Session node, in the two places a conftest gets parsed:

  1. _flush_pending_conftests_to_session — also flush the initial rootdir conftest (e.g. when it is the --config-file) to the Session.
  2. pytest_make_collect_report — when collecting the rootdir Directory, attach its conftest to the Session instead of the Directory.

This is safe:

  • Behavior-identical for normal layouts (everything under the rootdir): the Session is an ancestor of all items, so visibility is unchanged.
  • Preserves Conftest fixtures leak to sibling directories when testpaths points outside rootdir #14004: only the rootdir conftest is affected; nested conftests still scope to their own Directory, so sibling-leak does not return.
  • Fixture overrides still work: a subdir conftest remains more specific than the Session per is_visibility_more_specific, so it still wins.

Tests

  • testing/test_conftest.py::test_rootdir_conftest_visible_outside_rootdir
  • testing/test_doctest.py::TestDoctestNamespaceFixture::test_namespace_fixture_from_rootdir_when_modules_outside_rootdir (mirrors the reporter's exact --config-file + collect-from-parent pattern)

Both fail on main and pass with this change. Added news fragment changelog/14683.bugfix.rst.

Note on #14635

#14635 (Home Assistant, "fixtures not found when a parent directory appears multiple times in an argument list") is tracked as a duplicate and is being worked on separately by @RonnyPfannschmidt (multiple Directory nodes for the same path). This PR targets the rootdir-conftest visibility facet (#14683) only; making the rootdir conftest Session-visible also makes it more robust against the multi-node scenario, but it is not meant to be the complete fix for #14635.

…#14683)

A conftest located in the rootdir used to get an empty baseid (matching
every collected item), so its fixtures were visible session-wide. The
node-based scoping introduced in 46478fa (pytest-dev#14098, pytest 9.1) scoped it
to its own Directory node instead. When --rootdir points to a subdirectory
and tests/doctests are collected from a parent directory, that Directory is
not an ancestor of the collected items, so the conftest fixtures --
including doctest_namespace injections -- became invisible (NameError in
doctests).

Restore the pre-9.1 behavior by attaching the rootdir conftest to the
Session node, in both places a conftest is parsed: the initial-conftest
flush and the Directory collect report.

This is behavior-identical for normal layouts (the Session is an ancestor
of all items under the rootdir), preserves the pytest-dev#14004 sibling-leak fix,
and keeps fixture overrides working (a subdir conftest is still more
specific than the Session).
@psf-chronographer psf-chronographer Bot added the bot:chronographer:provided (automation) changelog entry is part of PR label Jul 11, 2026
@breidenbach0

Copy link
Copy Markdown
Author

Heads up on the two red CI jobs — both are a known repo-wide infra issue, unrelated to this change:

  • build (ubuntu-pypy3-xdist) fails during dependency installation (before any pytest code runs) while building hypothesis 6.156.6 from source:
    error: the configured PyPy interpreter version (3.10) is lower than PyO3's minimum supported version (3.11)
    
    The latest hypothesis now ships Rust extensions via maturin/pyo3 0.29, and pyo3 0.29 dropped Python 3.10 while the PyPy CI image is on 3.10. Since hypothesis is pinned only as >=3.56, pip pulls the incompatible latest.
  • check is just the re-actors/alls-green status gate — it fails solely as a downstream consequence of the pypy3-xdist failure.

For confirmation, another currently-open PR (#14693, unrelated) fails the identical two jobs with the same cause. All other jobs on this PR (macOS/Ubuntu, Python 3.10–3.15, xdist, plugins, doctesting, etc.) are green.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bot:chronographer:provided (automation) changelog entry is part of PR

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Variables injected in doctest_namespace no longer loaded in Pytest 9.1.x

1 participant