Merge pull request #667 from graingert/fix-sys-path
fix sys.path for local workers Fixes #421
This commit is contained in:
1
changelog/421.bugfix.rst
Normal file
1
changelog/421.bugfix.rst
Normal file
@@ -0,0 +1 @@
|
|||||||
|
Copy the parent process sys.path into local workers, to work around execnet's python -c adding the current directory to sys.path.
|
||||||
@@ -1,9 +1,12 @@
|
|||||||
import os
|
import os
|
||||||
import uuid
|
import uuid
|
||||||
|
import sys
|
||||||
|
|
||||||
import py
|
import py
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
|
_sys_path = list(sys.path) # freeze a copy of sys.path at interpreter startup
|
||||||
|
|
||||||
|
|
||||||
def pytest_xdist_auto_num_workers(config):
|
def pytest_xdist_auto_num_workers(config):
|
||||||
try:
|
try:
|
||||||
|
|||||||
@@ -219,12 +219,14 @@ if __name__ == "__channelexec__":
|
|||||||
channel = channel # noqa
|
channel = channel # noqa
|
||||||
workerinput, args, option_dict, change_sys_path = channel.receive()
|
workerinput, args, option_dict, change_sys_path = channel.receive()
|
||||||
|
|
||||||
if change_sys_path:
|
if change_sys_path is None:
|
||||||
importpath = os.getcwd()
|
importpath = os.getcwd()
|
||||||
sys.path.insert(0, importpath)
|
sys.path.insert(0, importpath)
|
||||||
os.environ["PYTHONPATH"] = (
|
os.environ["PYTHONPATH"] = (
|
||||||
importpath + os.pathsep + os.environ.get("PYTHONPATH", "")
|
importpath + os.pathsep + os.environ.get("PYTHONPATH", "")
|
||||||
)
|
)
|
||||||
|
else:
|
||||||
|
sys.path = change_sys_path
|
||||||
|
|
||||||
os.environ["PYTEST_XDIST_TESTRUNUID"] = workerinput["testrunuid"]
|
os.environ["PYTEST_XDIST_TESTRUNUID"] = workerinput["testrunuid"]
|
||||||
os.environ["PYTEST_XDIST_WORKER"] = workerinput["workerid"]
|
os.environ["PYTEST_XDIST_WORKER"] = workerinput["workerid"]
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import pytest
|
|||||||
import execnet
|
import execnet
|
||||||
|
|
||||||
import xdist.remote
|
import xdist.remote
|
||||||
|
from xdist.plugin import _sys_path
|
||||||
|
|
||||||
|
|
||||||
def parse_spec_config(config):
|
def parse_spec_config(config):
|
||||||
@@ -261,7 +262,8 @@ class WorkerController:
|
|||||||
remote_module = self.config.hook.pytest_xdist_getremotemodule()
|
remote_module = self.config.hook.pytest_xdist_getremotemodule()
|
||||||
self.channel = self.gateway.remote_exec(remote_module)
|
self.channel = self.gateway.remote_exec(remote_module)
|
||||||
# change sys.path only for remote workers
|
# change sys.path only for remote workers
|
||||||
change_sys_path = not self.gateway.spec.popen
|
# restore sys.path from a frozen copy for local workers
|
||||||
|
change_sys_path = _sys_path if self.gateway.spec.popen else None
|
||||||
self.channel.send((self.workerinput, args, option_dict, change_sys_path))
|
self.channel.send((self.workerinput, args, option_dict, change_sys_path))
|
||||||
|
|
||||||
if self.putevent:
|
if self.putevent:
|
||||||
|
|||||||
@@ -292,3 +292,17 @@ def test_remote_usage_prog(testdir, request):
|
|||||||
result = testdir.runpytest_subprocess("-n1")
|
result = testdir.runpytest_subprocess("-n1")
|
||||||
assert result.ret == 1
|
assert result.ret == 1
|
||||||
result.stdout.fnmatch_lines(["*usage: *", "*error: my_usage_error"])
|
result.stdout.fnmatch_lines(["*usage: *", "*error: my_usage_error"])
|
||||||
|
|
||||||
|
|
||||||
|
def test_remote_sys_path(testdir):
|
||||||
|
"""Work around sys.path differences due to execnet using `python -c`."""
|
||||||
|
testdir.makepyfile(
|
||||||
|
"""
|
||||||
|
import sys
|
||||||
|
|
||||||
|
def test_sys_path():
|
||||||
|
assert "" not in sys.path
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
result = testdir.runpytest("-n1")
|
||||||
|
assert result.ret == 0
|
||||||
|
|||||||
Reference in New Issue
Block a user