Skip to content

Commit b02a6db

Browse files
Merge pull request #667 from graingert/fix-sys-path
fix sys.path for local workers Fixes #421
2 parents 881cc48 + b072267 commit b02a6db

File tree

5 files changed

+24
-2
lines changed

5 files changed

+24
-2
lines changed

changelog/421.bugfix.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Copy the parent process sys.path into local workers, to work around execnet's python -c adding the current directory to sys.path.

src/xdist/plugin.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
11
import os
22
import uuid
3+
import sys
34

45
import py
56
import pytest
67

8+
_sys_path = list(sys.path) # freeze a copy of sys.path at interpreter startup
9+
710

811
def pytest_xdist_auto_num_workers(config):
912
try:

src/xdist/remote.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -219,12 +219,14 @@ def setup_config(config, basetemp):
219219
channel = channel # noqa
220220
workerinput, args, option_dict, change_sys_path = channel.receive()
221221

222-
if change_sys_path:
222+
if change_sys_path is None:
223223
importpath = os.getcwd()
224224
sys.path.insert(0, importpath)
225225
os.environ["PYTHONPATH"] = (
226226
importpath + os.pathsep + os.environ.get("PYTHONPATH", "")
227227
)
228+
else:
229+
sys.path = change_sys_path
228230

229231
os.environ["PYTEST_XDIST_TESTRUNUID"] = workerinput["testrunuid"]
230232
os.environ["PYTEST_XDIST_WORKER"] = workerinput["workerid"]

src/xdist/workermanage.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import execnet
1010

1111
import xdist.remote
12+
from xdist.plugin import _sys_path
1213

1314

1415
def parse_spec_config(config):
@@ -261,7 +262,8 @@ def setup(self):
261262
remote_module = self.config.hook.pytest_xdist_getremotemodule()
262263
self.channel = self.gateway.remote_exec(remote_module)
263264
# change sys.path only for remote workers
264-
change_sys_path = not self.gateway.spec.popen
265+
# restore sys.path from a frozen copy for local workers
266+
change_sys_path = _sys_path if self.gateway.spec.popen else None
265267
self.channel.send((self.workerinput, args, option_dict, change_sys_path))
266268

267269
if self.putevent:

testing/test_remote.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -292,3 +292,17 @@ def test(get_config_parser, request):
292292
result = testdir.runpytest_subprocess("-n1")
293293
assert result.ret == 1
294294
result.stdout.fnmatch_lines(["*usage: *", "*error: my_usage_error"])
295+
296+
297+
def test_remote_sys_path(testdir):
298+
"""Work around sys.path differences due to execnet using `python -c`."""
299+
testdir.makepyfile(
300+
"""
301+
import sys
302+
303+
def test_sys_path():
304+
assert "" not in sys.path
305+
"""
306+
)
307+
result = testdir.runpytest("-n1")
308+
assert result.ret == 0

0 commit comments

Comments
 (0)