Skip to content

Conversation

@tony
Copy link
Member

@tony tony commented Nov 25, 2025

Backport upstream doctest bug fixes and add pytest 7/8/9 compatibility

Summary

This PR backports critical bug fixes from upstream pytest and Sphinx, adds pytest version compatibility features, and ensures compatibility across pytest 7.x, 8.x, and 9.x.

Bug Fixes

pytest_doctest_docutils

doctest_docutils

New Features

pytest_doctest_docutils

  • _unblock_doctest() helper - Programmatic re-enabling of built-in doctest plugin
    • Uses public pluginmanager.unblock() API (pytest 8.1+)
    • Graceful fallback for older pytest versions

Development Improvements

CI Enhancements

  • Add pytest 9.x to test matrix
  • Add pytest 7.x/8.x compatibility testing
  • Exclude Python 3.14 + pytest 7 combination to reduce matrix size

Test Coverage

  • Plugin suppression tests for pytest 8.1+ unblock() API
  • Plugin suppression tests for pytest 8.4+ --disable-plugin-autoload flag
  • Comprehensive doctest option flag tests (ELLIPSIS, SKIP, NORMALIZE_WHITESPACE, etc.)
  • Autouse fixture regression tests across multiple scopes and file formats
  • Whitespace handling regression tests

Code Quality

  • Remove dead _from_module() method (unused since Python 3.13+)
  • Add version detection utilities for pytest compatibility

Documentation

  • Add comprehensive upstream audit report at notes/2025-11-25-upstream-backports.md
  • Update CHANGES for 0.0.16 release

@codecov
Copy link

codecov bot commented Nov 25, 2025

Codecov Report

❌ Patch coverage is 93.36283% with 15 lines in your changes missing coverage. Please review.
✅ Project coverage is 71.11%. Comparing base (9382afd) to head (fc18c45).
⚠️ Report is 17 commits behind head on master.

Files with missing lines Patch % Lines
src/pytest_doctest_docutils.py 14.28% 6 Missing ⚠️
tests/test_doctest_options.py 94.56% 5 Missing ⚠️
tests/test_plugin_suppression.py 96.77% 3 Missing ⚠️
src/doctest_docutils.py 0.00% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master      #56      +/-   ##
==========================================
+ Coverage   62.58%   71.11%   +8.52%     
==========================================
  Files          11       14       +3     
  Lines         695      914     +219     
==========================================
+ Hits          435      650     +215     
- Misses        260      264       +4     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

tony added a commit that referenced this pull request Nov 25, 2025
what:
- pytest autouse fixtures fix (backport from pytest 9cd14b4ff)
- doctest directive whitespace fix (backport from Sphinx ad0c343d3)
tony added a commit that referenced this pull request Nov 25, 2025
Backport: pytest commit 9cd14b4ff (2024-02-06)
Ref: pytest-dev/pytest@9cd14b4ff

what:
- Test autouse fixtures from conftest.py with .rst/.md doctests
- Parametrized over scopes: module, session, class, function
- Parametrized over file types: .rst, .md (8 test cases total)

Refs: pytest-dev/pytest#11929
tony added a commit that referenced this pull request Nov 25, 2025
Backport: Sphinx commit ad0c343d3 (2025-01-04)
Ref: sphinx-doc/sphinx@ad0c343d3

what:
- Test doctestopt_re regex removes leading whitespace before flags
- Covers trailing spaces, tabs, multiline, mixed whitespace
- 6 test cases using NamedTuple parametrization

Refs: sphinx-doc/sphinx#13164
tony added 7 commits November 25, 2025 11:20
why: Document analysis of upstream changes for informed backporting decisions
what:
- Comprehensive audit of 115 commits across CPython, pytest, and Sphinx (2022-2025)
- Documents applicability of each commit to gp-libs architecture
- Identifies 2 backports needed: pytest 9cd14b4ff, Sphinx ad0c343d3
- Explains why gp-libs inherits most fixes automatically via stdlib/dependencies
Backport: pytest commit 9cd14b4ff (2024-02-06)
Ref: pytest-dev/pytest@9cd14b4ff

why: Autouse fixtures were not being discovered for doctest files
what:
- Add parsefactories() call to DocTestDocutilsFile.collect()
- Ensures session fixture manager processes the doctest module
- Allows autouse fixtures from conftest.py to apply to doctests
Backport: Sphinx commit ad0c343d3 (2025-01-04)
Ref: sphinx-doc/sphinx@ad0c343d3

why: Doctest directive comments with leading whitespace were not recognized
what:
- Add [ \t]* prefix to doctestopt_re pattern
- Allows doctest options like "  # doctest: +SKIP" to be properly parsed
- Fixes edge case where indented doctest directive comments were ignored
…module method

why: Method is unreachable and would fail if called
what:
- Remove _from_module override from DocutilsDocTestFinder
- Method called super()._from_module() but class has no parent
- Copied from pytest's MockAwareDocTestFinder but not applicable here
- DocutilsDocTestFinder parses documents, not Python modules
- Remove unused functools import
what:
- pytest autouse fixtures fix (backport from pytest 9cd14b4ff)
- doctest directive whitespace fix (backport from Sphinx ad0c343d3)
Backport: pytest commit 9cd14b4ff (2024-02-06)
Ref: pytest-dev/pytest@9cd14b4ff

what:
- Test autouse fixtures from conftest.py with .rst/.md doctests
- Parametrized over scopes: module, session, class, function
- Parametrized over file types: .rst, .md (8 test cases total)

Refs: pytest-dev/pytest#11929
Backport: Sphinx commit ad0c343d3 (2025-01-04)
Ref: sphinx-doc/sphinx@ad0c343d3

what:
- Test doctestopt_re regex removes leading whitespace before flags
- Covers trailing spaces, tabs, multiline, mixed whitespace
- 6 test cases using NamedTuple parametrization

Refs: sphinx-doc/sphinx#13164
@tony tony force-pushed the 2025-11-25-backports branch from cdda92f to ed9c8bd Compare November 25, 2025 17:20
tony added 9 commits November 25, 2025 13:21
…outing tests

why: Ensure plugin suppression/precedence works correctly across pytest 7.x/8.x
what:
- Test automatic doctest plugin blocking via pytest_configure
- Test explicit -p no:doctest behavior with addopts
- Test restoring builtin doctest via -p no:pytest_doctest_docutils
- Test plugin precedence with -p no:X -p X patterns
- Test collector routing: .py uses DoctestModule, .rst/.md use DocTestDocutilsFile
- Use NamedTuple + test_id parametrization pattern

Ref: pytest's test_pluginmanager.py (lines 442-483) for plugin blocking patterns
why: Ensure doctest options work correctly in document files
what:
- Test ELLIPSIS, NORMALIZE_WHITESPACE via doctest_optionflags ini setting
- Test combined ELLIPSIS + NORMALIZE_WHITESPACE
- Test inline # doctest: +SKIP and +ELLIPSIS directives
- Test --doctest-continue-on-failure behavior
- Test custom flags: ALLOW_UNICODE, NUMBER
- Test edge cases: empty files, files without doctests
- Use NamedTuple + test_id parametrization pattern

Ref: pytest's test_doctest.py option flag test patterns
why: Ensure plugin works across recent pytest major versions
what:
- Add pytest-version matrix to CI workflow (pytest 7 and 8)
- Install specific pytest version after uv sync
- Print pytest version in CI logs for verification
- Exclude pytest 7 from Python 3.14 (reduce matrix size)
why: Ensure plugin compatibility with latest pytest major version
what:
- Add pytest 9 to CI test matrix alongside pytest 7 and 8
- Tests now run against all three recent major versions
why: Test new pluginmanager.unblock() API introduced in pytest 8.1.0
what:
- Add PYTEST_VERSION constant for version detection
- Add requires_pytest_version() marker helper for version-specific tests
- Add test_unblock_api_available() for pytest 8.1+ unblock() API
- Test skips automatically on pytest < 8.1

Ref: pytest 8.1.0 changelog - pluginmanager.unblock() public API
why: Test new --disable-plugin-autoload CLI flag introduced in pytest 8.4.0
what:
- Add test_disable_plugin_autoload_flag() for flag recognition
- Add test_disable_plugin_autoload_with_explicit_plugin() for explicit plugin loading
- Tests skip automatically on pytest < 8.4

Ref: pytest 8.4.0 changelog - --disable-plugin-autoload CLI flag
… 8.1+

why: Enable programmatic re-enabling of built-in doctest plugin using
the public unblock() API introduced in pytest 8.1.0.
what:
- Add PYTEST_VERSION constant for version-specific feature detection
- Add _unblock_doctest() helper that uses pluginmanager.unblock() when
  available, with graceful fallback for older pytest versions
@tony tony merged commit fd7e17e into master Nov 25, 2025
36 checks passed
@tony tony deleted the 2025-11-25-backports branch November 25, 2025 21:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

pytest 8.0.0 ignores autouse fixtures in doctest modules when collecting packages

2 participants