Skip to content

Commit 8eb3804

Browse files
authored
pytester: only change HOME when not changed in fixtures (#485)
1 parent 2d06c84 commit 8eb3804

File tree

2 files changed

+63
-35
lines changed

2 files changed

+63
-35
lines changed

src/_pytest/pytester/__init__.py

Lines changed: 45 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,8 @@ def pytest_configure(config):
9898
if checker.matching_platform():
9999
config.pluginmanager.register(checker)
100100

101+
config.pluginmanager.register(PytesterManageEnv())
102+
101103
config.addinivalue_line(
102104
"markers",
103105
"pytester_example_path(*path_segments): join the given path "
@@ -539,42 +541,50 @@ def _display_running(header: str, *args: str) -> None:
539541
print("{}: {}\n{}in: {}".format(header, args_str, indent, cwd))
540542

541543

542-
@pytest.hookimpl(hookwrapper=True, trylast=True)
543-
def pytest_runtest_call(item: Function) -> Generator[None, None, None]:
544-
"""Setup/activate testdir's monkeypatching only during test calls.
545-
546-
When it would be done via the instance/fixture directly it would also be
547-
active during teardown (e.g. with the terminal plugin's reporting), where
548-
it might mess with the column width etc.
549-
"""
550-
try:
551-
funcargs = item.funcargs
552-
except AttributeError:
553-
testdir = None
554-
else:
555-
testdir = funcargs.get("testdir")
556-
if not isinstance(testdir, Testdir):
557-
yield
558-
return
559-
560-
mp = testdir.monkeypatch
561-
mp.setenv("PYTEST_DEBUG_TEMPROOT", str(testdir.test_tmproot))
562-
# Ensure no unexpected caching via tox.
563-
mp.delenv("TOX_ENV_DIR", raising=False)
564-
# Discard outer pytest options.
565-
mp.delenv("PYTEST_ADDOPTS", raising=False)
566-
# Ensure no user config is used.
567-
tmphome = str(testdir.tmpdir)
568-
mp.setenv("HOME", tmphome)
569-
mp.setenv("USERPROFILE", tmphome)
570-
# Do not use colors for inner runs by default.
571-
mp.setenv("PY_COLORS", "0")
572-
573-
mp.setattr("_pytest.terminal.get_terminal_width", lambda: 80)
574-
try:
544+
class PytesterManageEnv:
545+
@pytest.hookimpl(hookwrapper=True, tryfirst=True)
546+
def pytest_runtest_setup(self):
547+
initial_home = os.getenv("HOME")
575548
yield
576-
finally:
577-
mp.undo()
549+
self._initial_home_changed = os.getenv("HOME") != initial_home
550+
551+
@pytest.hookimpl(hookwrapper=True, trylast=True)
552+
def pytest_runtest_call(self, item: Function) -> Generator[None, None, None]:
553+
"""Setup/activate testdir's monkeypatching only during test calls.
554+
555+
When it would be done via the instance/fixture directly it would also be
556+
active during teardown (e.g. with the terminal plugin's reporting), where
557+
it might mess with the column width etc.
558+
"""
559+
try:
560+
funcargs = item.funcargs
561+
except AttributeError:
562+
testdir = None
563+
else:
564+
testdir = funcargs.get("testdir")
565+
if not isinstance(testdir, Testdir):
566+
yield
567+
return
568+
569+
mp = testdir.monkeypatch
570+
mp.setenv("PYTEST_DEBUG_TEMPROOT", str(testdir.test_tmproot))
571+
# Ensure no unexpected caching via tox.
572+
mp.delenv("TOX_ENV_DIR", raising=False)
573+
# Discard outer pytest options.
574+
mp.delenv("PYTEST_ADDOPTS", raising=False)
575+
# Ensure no user config is used.
576+
if not self._initial_home_changed:
577+
tmphome = str(testdir.tmpdir)
578+
mp.setenv("HOME", tmphome)
579+
mp.setenv("USERPROFILE", tmphome)
580+
# Do not use colors for inner runs by default.
581+
mp.setenv("PY_COLORS", "0")
582+
583+
mp.setattr("_pytest.terminal.get_terminal_width", lambda: 80)
584+
try:
585+
yield
586+
finally:
587+
mp.undo()
578588

579589

580590
class Testdir(Generic[AnyStr]):

testing/test_pytester.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1433,3 +1433,21 @@ def test_makefiles_sequence_duplicate(self, testdir: "Testdir") -> None:
14331433
)
14341434
assert tuple(x.name for x in files) == ("1", "2", "1")
14351435
assert tuple(x.read_text() for x in files) == ("foo2", "bar", "foo2")
1436+
1437+
1438+
def test_home_used_from_fixture(testdir: "Testdir") -> None:
1439+
p1 = testdir.makepyfile(
1440+
"""
1441+
import os
1442+
import pytest
1443+
1444+
@pytest.fixture
1445+
def fix():
1446+
os.environ["HOME"] = "/new/home"
1447+
1448+
def test(testdir, fix):
1449+
assert os.environ["HOME"] == "/new/home"
1450+
"""
1451+
)
1452+
result = testdir.runpytest(p1, "-ppytester")
1453+
assert result.ret == 0

0 commit comments

Comments
 (0)