Skip to content

Commit 2c03a22

Browse files
committed
pytester now requests monkeypatch instead of creating its own instance
It is tempting to use `monkeypatch` to replace the other mechanisms in pytester which change global state: `CwdSnapshot`, `SysModulesSnapshot`, `SysPathsSnapshot`, however those are more delicate than they look at first glance so leaving those alone for now. Close pytest-dev#9708
1 parent 5f3d94c commit 2c03a22

File tree

3 files changed

+8
-10
lines changed

3 files changed

+8
-10
lines changed

changelog/9708.bugfix.rst

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
:fixture:`pytester` now requests a :fixture:`monkeypatch` fixture instead of creating one internally. This solves some issues with tests that involve pytest environment variables.

src/_pytest/pytester.py

+6-4
Original file line numberDiff line numberDiff line change
@@ -477,7 +477,9 @@ def LineMatcher_fixture(request: FixtureRequest) -> Type["LineMatcher"]:
477477

478478

479479
@fixture
480-
def pytester(request: FixtureRequest, tmp_path_factory: TempPathFactory) -> "Pytester":
480+
def pytester(
481+
request: FixtureRequest, tmp_path_factory: TempPathFactory, monkeypatch: MonkeyPatch
482+
) -> "Pytester":
481483
"""
482484
Facilities to write tests/configuration files, execute pytest in isolation, and match
483485
against expected output, perfect for black-box testing of pytest plugins.
@@ -488,7 +490,7 @@ def pytester(request: FixtureRequest, tmp_path_factory: TempPathFactory) -> "Pyt
488490
It is particularly useful for testing plugins. It is similar to the :fixture:`tmp_path`
489491
fixture but provides methods which aid in testing pytest itself.
490492
"""
491-
return Pytester(request, tmp_path_factory, _ispytest=True)
493+
return Pytester(request, tmp_path_factory, monkeypatch, _ispytest=True)
492494

493495

494496
@fixture
@@ -683,6 +685,7 @@ def __init__(
683685
self,
684686
request: FixtureRequest,
685687
tmp_path_factory: TempPathFactory,
688+
monkeypatch: MonkeyPatch,
686689
*,
687690
_ispytest: bool = False,
688691
) -> None:
@@ -706,7 +709,7 @@ def __init__(
706709
self._method = self._request.config.getoption("--runpytest")
707710
self._test_tmproot = tmp_path_factory.mktemp(f"tmp-{name}", numbered=True)
708711

709-
self._monkeypatch = mp = MonkeyPatch()
712+
self._monkeypatch = mp = monkeypatch
710713
mp.setenv("PYTEST_DEBUG_TEMPROOT", str(self._test_tmproot))
711714
# Ensure no unexpected caching via tox.
712715
mp.delenv("TOX_ENV_DIR", raising=False)
@@ -738,7 +741,6 @@ def _finalize(self) -> None:
738741
self._sys_modules_snapshot.restore()
739742
self._sys_path_snapshot.restore()
740743
self._cwd_snapshot.restore()
741-
self._monkeypatch.undo()
742744

743745
def __take_sys_modules_snapshot(self) -> SysModulesSnapshot:
744746
# Some zope modules used by twisted-related tests keep internal state

testing/test_pytester.py

+1-6
Original file line numberDiff line numberDiff line change
@@ -618,14 +618,9 @@ def test_linematcher_string_api() -> None:
618618

619619

620620
def test_pytest_addopts_before_pytester(request, monkeypatch: MonkeyPatch) -> None:
621-
orig = os.environ.get("PYTEST_ADDOPTS", None)
622621
monkeypatch.setenv("PYTEST_ADDOPTS", "--orig-unused")
623-
pytester: Pytester = request.getfixturevalue("pytester")
622+
_: Pytester = request.getfixturevalue("pytester")
624623
assert "PYTEST_ADDOPTS" not in os.environ
625-
pytester._finalize()
626-
assert os.environ.get("PYTEST_ADDOPTS") == "--orig-unused"
627-
monkeypatch.undo()
628-
assert os.environ.get("PYTEST_ADDOPTS") == orig
629624

630625

631626
def test_run_stdin(pytester: Pytester) -> None:

0 commit comments

Comments
 (0)