Merge pull request #11941 from bluetech/doctest-parsefactories

doctest: fix autouse fixtures possibly not getting picked up
This commit is contained in:
Ran Benita 2024-02-07 22:09:17 +02:00 committed by GitHub
commit 6c0b6c2f92
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 40 additions and 8 deletions

View File

@ -0,0 +1 @@
Fix a regression in pytest 8.0.0 whereby autouse fixtures defined in a module get ignored by the doctests in the module.

View File

@ -40,7 +40,6 @@ from _pytest.nodes import Item
from _pytest.outcomes import OutcomeException from _pytest.outcomes import OutcomeException
from _pytest.outcomes import skip from _pytest.outcomes import skip
from _pytest.pathlib import fnmatch_ex from _pytest.pathlib import fnmatch_ex
from _pytest.pathlib import import_path
from _pytest.python import Module from _pytest.python import Module
from _pytest.python_api import approx from _pytest.python_api import approx
from _pytest.warning_types import PytestWarning from _pytest.warning_types import PytestWarning
@ -107,7 +106,7 @@ def pytest_addoption(parser: Parser) -> None:
"--doctest-ignore-import-errors", "--doctest-ignore-import-errors",
action="store_true", action="store_true",
default=False, default=False,
help="Ignore doctest ImportErrors", help="Ignore doctest collection errors",
dest="doctest_ignore_import_errors", dest="doctest_ignore_import_errors",
) )
group.addoption( group.addoption(
@ -561,17 +560,17 @@ class DoctestModule(Module):
pass pass
try: try:
module = import_path( module = self.obj
self.path, except Collector.CollectError:
root=self.config.rootpath,
mode=self.config.getoption("importmode"),
)
except ImportError:
if self.config.getvalue("doctest_ignore_import_errors"): if self.config.getvalue("doctest_ignore_import_errors"):
skip("unable to import module %r" % self.path) skip("unable to import module %r" % self.path)
else: else:
raise raise
# While doctests currently don't support fixtures directly, we still
# need to pick up autouse fixtures.
self.session._fixturemanager.parsefactories(self)
# Uses internal doctest module parsing mechanism. # Uses internal doctest module parsing mechanism.
finder = MockAwareDocTestFinder() finder = MockAwareDocTestFinder()
optionflags = get_optionflags(self.config) optionflags = get_optionflags(self.config)

View File

@ -1376,6 +1376,38 @@ class TestDoctestAutoUseFixtures:
str(result.stdout.no_fnmatch_line("*FAILURES*")) str(result.stdout.no_fnmatch_line("*FAILURES*"))
result.stdout.fnmatch_lines(["*=== 1 passed in *"]) result.stdout.fnmatch_lines(["*=== 1 passed in *"])
@pytest.mark.parametrize("scope", [*SCOPES, "package"])
def test_auto_use_defined_in_same_module(
self, pytester: Pytester, scope: str
) -> None:
"""Autouse fixtures defined in the same module as the doctest get picked
up properly.
Regression test for #11929.
"""
pytester.makepyfile(
f"""
import pytest
AUTO = "the fixture did not run"
@pytest.fixture(autouse=True, scope="{scope}")
def auto(request):
global AUTO
AUTO = "the fixture ran"
def my_doctest():
'''My doctest.
>>> my_doctest()
'the fixture ran'
'''
return AUTO
"""
)
result = pytester.runpytest("--doctest-modules")
result.assert_outcomes(passed=1)
class TestDoctestNamespaceFixture: class TestDoctestNamespaceFixture:
SCOPES = ["module", "session", "class", "function"] SCOPES = ["module", "session", "class", "function"]