From 486353c70ce3bc2ce8a77619c6b6cbdc5b2d91cf Mon Sep 17 00:00:00 2001 From: Daniel Hahler Date: Fri, 3 Apr 2020 07:19:33 +0200 Subject: [PATCH 1/2] Fix tests: use explicit syspathinsert Use `testdir.syspathinsert()` with multiprocessing tests: - `test_chained_exceptions_no_reprcrash` - `test_exception_handling_no_traceback` This only works currently because `_importtestmodule` changes `sys.path` as a side-effect. It appears to be only required on Windows though - likely due to the multiprocessing method used there. --- testing/test_assertion.py | 1 + testing/test_reports.py | 1 + 2 files changed, 2 insertions(+) diff --git a/testing/test_assertion.py b/testing/test_assertion.py index 3d8fa912272..c97da3a024f 100644 --- a/testing/test_assertion.py +++ b/testing/test_assertion.py @@ -1409,6 +1409,7 @@ def test_multitask_job(): multitask_job() """ ) + testdir.syspathinsert() result = testdir.runpytest(p1, "--tb=long") result.stdout.fnmatch_lines( [ diff --git a/testing/test_reports.py b/testing/test_reports.py index 8c509ec479d..13f5932156b 100644 --- a/testing/test_reports.py +++ b/testing/test_reports.py @@ -362,6 +362,7 @@ def test_a(): """ ) + testdir.syspathinsert() reprec = testdir.inline_run() reports = reprec.getreports("pytest_runtest_logreport") From 9b06f36a574b27dabf5528b9ecf11b38ec05ba6b Mon Sep 17 00:00:00 2001 From: Daniel Hahler Date: Thu, 2 Apr 2020 14:45:45 +0200 Subject: [PATCH 2/2] Restore sys.path after importing test modules Ref: https://github.com/pytest-dev/pytest/issues/5147#issuecomment-607752141 --- src/_pytest/python.py | 4 ++++ testing/python/collect.py | 15 +++++++++++++++ testing/test_assertrewrite.py | 1 + testing/test_monkeypatch.py | 4 +++- 4 files changed, 23 insertions(+), 1 deletion(-) diff --git a/src/_pytest/python.py b/src/_pytest/python.py index 372631f107d..33ef086b0d0 100644 --- a/src/_pytest/python.py +++ b/src/_pytest/python.py @@ -515,6 +515,7 @@ def _importtestmodule(self) -> ModuleType: # we assume we are only called once per module importmode = self.config.getoption("--import-mode") fspath = self.fspath + old_sys_path = sys.path[:] if importmode != "importlib" else None try: mod = fspath.pyimport(ensuresyspath=importmode) except SyntaxError: @@ -554,6 +555,9 @@ def _importtestmodule(self) -> ModuleType: "or @pytest.mark.skipif decorators instead, and to skip a " "module use `pytestmark = pytest.mark.{skip,skipif}." ) + finally: + if old_sys_path: + sys.path[:] = old_sys_path self.config.pluginmanager.consider_module(mod) return mod diff --git a/testing/python/collect.py b/testing/python/collect.py index 7062740b88c..eb5eca9d58a 100644 --- a/testing/python/collect.py +++ b/testing/python/collect.py @@ -56,6 +56,21 @@ def test(): reprec = testdir.inline_run() reprec.assertoutcome(passed=1) + @pytest.mark.parametrize("import_mode", ("append", "prepend", "importlib")) + def test__importtestmodule_restores_sys_path(self, import_mode, testdir): + p1 = testdir.makepyfile( + """ + import sys + + def test(): + assert sys.path == {!r} + """.format( + sys.path + ) + ) + reprec = testdir.inline_run("--import-mode={}".format(import_mode), str(p1)) + reprec.assertoutcome(passed=1) + def test_syntax_error_in_module(self, testdir): modcol = testdir.getmodulecol("this is a syntax error") pytest.raises(modcol.CollectError, modcol.collect) diff --git a/testing/test_assertrewrite.py b/testing/test_assertrewrite.py index 36652dee54f..268c0ad77ff 100644 --- a/testing/test_assertrewrite.py +++ b/testing/test_assertrewrite.py @@ -1070,6 +1070,7 @@ def test_loader(): assert file.reloaded() """, ) + testdir.syspathinsert() result = testdir.runpytest() result.stdout.fnmatch_lines(["* 1 passed*"]) diff --git a/testing/test_monkeypatch.py b/testing/test_monkeypatch.py index 72f4cc85b9c..fd96df4b829 100644 --- a/testing/test_monkeypatch.py +++ b/testing/test_monkeypatch.py @@ -5,6 +5,7 @@ import pytest from _pytest.monkeypatch import MonkeyPatch +from _pytest.pytester import Testdir @pytest.fixture @@ -318,7 +319,8 @@ def f(): ) -def test_importerror(testdir): +def test_importerror(testdir: Testdir) -> None: + testdir.syspathinsert() p = testdir.mkpydir("package") p.join("a.py").write( textwrap.dedent(