pytester: remove special handling of env during inner runs#6219
pytester: remove special handling of env during inner runs#6219blueyed merged 1 commit intopytest-dev:featuresfrom
Conversation
7908b3f to
ba5b75c
Compare
ba5b75c to
d47d808
Compare
d47d808 to
ca7aa67
Compare
RonnyPfannschmidt
left a comment
There was a problem hiding this comment.
sorry i missed that detail before
RonnyPfannschmidt
left a comment
There was a problem hiding this comment.
sorry, also pressed the wrong button
6e50749 to
8c47ce9
Compare
This gets done via the fixture itself. Ref: pytest-dev#6219 (comment)
2a3918d to
1c008e4
Compare
|
I've extended |
Hmmm what if we just set HOME and USERPROFILE during diff --git a/src/_pytest/pytester.py b/src/_pytest/pytester.py
index ca780a9f5..63384261b 100644
--- a/src/_pytest/pytester.py
+++ b/src/_pytest/pytester.py
@@ -359,8 +359,8 @@ def LineMatcher_fixture(request: FixtureRequest) -> "Type[LineMatcher]":
@pytest.fixture
-def testdir(request: FixtureRequest, tmpdir_factory) -> "Testdir":
- return Testdir(request, tmpdir_factory)
+def testdir(request: FixtureRequest, tmpdir_factory, monkeypatch) -> "Testdir":
+ return Testdir(request, tmpdir_factory, monkeypatch)
@pytest.fixture
@@ -524,7 +524,7 @@ class Testdir:
class TimeoutExpired(Exception):
pass
- def __init__(self, request, tmpdir_factory):
+ def __init__(self, request, tmpdir_factory, monkeypatch):
self.request = request
self._mod_collections = WeakKeyDictionary()
name = request.function.__name__
@@ -547,7 +547,12 @@ class Testdir:
# Environment (updates) for inner runs.
tmphome = str(self.tmpdir)
- self._env_run_update = {"HOME": tmphome, "USERPROFILE": tmphome}
+ self.monkeypatch = monkeypatch
+ if sys.platform.startswith("win"):
+ self.monkeypatch.setenv("USERPROFILE", tmphome)
+ else:
+ self.monkeypatch.setenv("HOME", tmphome)
+ self.monkeypatch.delenv("PYTEST_ADDOPTS", raising=False)
def __repr__(self):
return "<Testdir {!r}>".format(self.tmpdir)
@@ -853,12 +858,6 @@ class Testdir:
plugins = list(plugins)
finalizers = []
try:
- # Do not load user config (during runs only).
- mp_run = MonkeyPatch()
- for k, v in self._env_run_update.items():
- mp_run.setenv(k, v)
- finalizers.append(mp_run.undo)
-
# Any sys.module or sys.path changes done while running pytest
# inline should be reverted after the test run completes to avoid
# clashing with later inline tests run within the same pytest test,
@@ -1091,7 +1090,6 @@ class Testdir:
env["PYTHONPATH"] = os.pathsep.join(
filter(None, [os.getcwd(), env.get("PYTHONPATH", "")])
)
- env.update(self._env_run_update)
kw["env"] = env
if stdin is Testdir.CLOSE_STDIN:
@@ -1261,11 +1259,7 @@ class Testdir:
pytest.skip("pexpect.spawn not available")
logfile = self.tmpdir.join("spawn.out").open("wb")
- # Do not load user config.
- env = os.environ.copy()
- env.update(self._env_run_update)
-
- child = pexpect.spawn(cmd, logfile=logfile, env=env)
+ child = pexpect.spawn(cmd, logfile=logfile)
self.request.addfinalizer(logfile.close)
child.timeout = expect_timeout
return child
diff --git a/testing/test_pytester.py b/testing/test_pytester.py
index 758e999dc..8a044cb1a 100644
--- a/testing/test_pytester.py
+++ b/testing/test_pytester.py
@@ -674,3 +674,26 @@ def test_run_result_repr():
repr(r) == "<RunResult ret=99 len(stdout.lines)=3"
" len(stderr.lines)=4 duration=0.50s>"
)
+
+
+@pytest.mark.parametrize("method", ("setenv", "delenv"))
+def test_testdir_respects_monkeypatch(method, testdir, monkeypatch):
+ testdir.makepyfile("""
+ import os
+ def test_home():
+ print("HOME:", os.environ.get("HOME"))
+ """)
+
+ if method == "setenv":
+ monkeypatch.setenv("HOME", "anotherhome")
+ else:
+ assert method == "delenv"
+ monkeypatch.delenv("HOME", raising=False)
+
+ result = testdir.runpytest("-vs")
+
+ if method == "setenv":
+ result.stdout.fnmatch_lines("*HOME: anotherhome*")
+ else:
+ assert method == "delenv"
+ result.stdout.fnmatch_lines("*HOME: None*")
This of course changes the behavior a bit, because the environment variables will be changed for the entire run, not only for the inner run... |
testing/test_pytester.py
Outdated
|
|
||
| assert os.environ["PYTEST_ADDOPTS"] == "--orig-unused" | ||
| @pytest.mark.parametrize("method", ("setenv", "delenv")) | ||
| def test_testdir_respects_monkeypatch(method, testdir, monkeypatch): |
There was a problem hiding this comment.
Regardless if we follow my previous suggestion about using monkeypatch during Testdir.__init__, can we have a more user facing test here? The test I posted also works on your branch, and tests the actual behavior we want:
@pytest.mark.parametrize("method", ("setenv", "delenv"))
def test_testdir_respects_monkeypatch(method, testdir, monkeypatch):
testdir.makepyfile("""
import os
def test_home():
print("HOME:", os.environ.get("HOME"))
""")
if method == "setenv":
monkeypatch.setenv("HOME", "anotherhome")
else:
assert method == "delenv"
monkeypatch.delenv("HOME", raising=False)
result = testdir.runpytest("-vs")
if method == "setenv":
result.stdout.fnmatch_lines("*HOME: anotherhome*")
else:
assert method == "delenv"
result.stdout.fnmatch_lines("*HOME: None*")There was a problem hiding this comment.
Not strictly opposed - my initial test was meant to be a unit test for _get_env_run_update (which would be gone then though). It's much faster though (1.2s for 100 runs (200 passes), compared to 20s for the above).
There was a problem hiding this comment.
Well I fear that by testing the inner mechanism and not testing the expected behavior, we might introduce a regression later and fail to notice. But I will leave this one to you.
There was a problem hiding this comment.
I think this is covered by existing/changed tests.
…
Which makes a difference for It does not need to use the existing/global monkeypatch fixture in the first place anymore then though, does it? |
|
I'll change it, removing |
1c008e4 to
e6d54f7
Compare
|
@RonnyPfannschmidt @nicoddemus |
e6d54f7 to
b0ebcfb
Compare
|
@nicoddemus |
|
LGTM 👍 |
|
Thanks for the reviews - this unblocks #6164 then. |
No description provided.