Pass and use original sys.argv to/with workers
This gets used e.g. by argparse for the "prog" part. We could explicitly pass it through and/or set it on config._parser.prog, but that is a bit tedious just for this use case, and it looks like "simulating" the main prog here appears to not be that bad of a hack after all.
This commit is contained in:
3
changelog/388.feature.rst
Normal file
3
changelog/388.feature.rst
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
``mainargv`` is made available in ``workerinput`` from the host's ``sys.argv``.
|
||||||
|
|
||||||
|
This can be used via ``request.config.workerinput["mainargv"]``.
|
||||||
@@ -1,6 +1,8 @@
|
|||||||
|
import os
|
||||||
import py
|
import py
|
||||||
import pprint
|
import pprint
|
||||||
import pytest
|
import pytest
|
||||||
|
import sys
|
||||||
|
|
||||||
from xdist.workermanage import WorkerController, unserialize_report
|
from xdist.workermanage import WorkerController, unserialize_report
|
||||||
from xdist.remote import serialize_report
|
from xdist.remote import serialize_report
|
||||||
@@ -397,3 +399,68 @@ def test_remote_env_vars(testdir):
|
|||||||
)
|
)
|
||||||
result = testdir.runpytest("-n2", "--max-worker-restart=0")
|
result = testdir.runpytest("-n2", "--max-worker-restart=0")
|
||||||
assert result.ret == 0
|
assert result.ret == 0
|
||||||
|
|
||||||
|
|
||||||
|
def test_remote_inner_argv(testdir):
|
||||||
|
"""Test/document the behavior due to execnet using `python -c`."""
|
||||||
|
testdir.makepyfile(
|
||||||
|
"""
|
||||||
|
import sys
|
||||||
|
|
||||||
|
def test_argv():
|
||||||
|
assert sys.argv == ["-c"]
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
result = testdir.runpytest("-n1")
|
||||||
|
assert result.ret == 0
|
||||||
|
|
||||||
|
|
||||||
|
def test_remote_mainargv(testdir):
|
||||||
|
outer_argv = sys.argv
|
||||||
|
|
||||||
|
testdir.makepyfile(
|
||||||
|
"""
|
||||||
|
def test_mainargv(request):
|
||||||
|
assert request.config.workerinput["mainargv"] == {!r}
|
||||||
|
""".format(
|
||||||
|
outer_argv
|
||||||
|
)
|
||||||
|
)
|
||||||
|
result = testdir.runpytest("-n1")
|
||||||
|
assert result.ret == 0
|
||||||
|
|
||||||
|
|
||||||
|
def test_remote_usage_prog(testdir, request):
|
||||||
|
if not hasattr(request.config._parser, "prog"):
|
||||||
|
pytest.skip("prog not available in config parser")
|
||||||
|
prog = os.path.basename(sys.argv[0])
|
||||||
|
|
||||||
|
testdir.makeconftest(
|
||||||
|
"""
|
||||||
|
import pytest
|
||||||
|
|
||||||
|
config_parser = None
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def get_config_parser():
|
||||||
|
return config_parser
|
||||||
|
|
||||||
|
def pytest_configure(config):
|
||||||
|
global config_parser
|
||||||
|
config_parser = config._parser
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
testdir.makepyfile(
|
||||||
|
"""
|
||||||
|
import sys
|
||||||
|
|
||||||
|
def test(get_config_parser, request):
|
||||||
|
get_config_parser._getparser().error("my_usage_error")
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
|
||||||
|
result = testdir.runpytest_subprocess("-n1")
|
||||||
|
assert result.ret == 1
|
||||||
|
result.stdout.fnmatch_lines(
|
||||||
|
["usage: %s *" % prog, "%s: error: my_usage_error" % prog]
|
||||||
|
)
|
||||||
|
|||||||
@@ -261,6 +261,7 @@ if __name__ == "__channelexec__":
|
|||||||
import py
|
import py
|
||||||
|
|
||||||
config = remote_initconfig(option_dict, args)
|
config = remote_initconfig(option_dict, args)
|
||||||
|
config._parser.prog = os.path.basename(workerinput["mainargv"][0])
|
||||||
config.workerinput = workerinput
|
config.workerinput = workerinput
|
||||||
config.workeroutput = {}
|
config.workeroutput = {}
|
||||||
# TODO: deprecated name, backward compatibility only. Remove it in future
|
# TODO: deprecated name, backward compatibility only. Remove it in future
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ from __future__ import print_function
|
|||||||
import fnmatch
|
import fnmatch
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
|
import sys
|
||||||
import threading
|
import threading
|
||||||
|
|
||||||
import py
|
import py
|
||||||
@@ -213,6 +214,7 @@ class WorkerController(object):
|
|||||||
"workercount": len(nodemanager.specs),
|
"workercount": len(nodemanager.specs),
|
||||||
"slaveid": gateway.id,
|
"slaveid": gateway.id,
|
||||||
"slavecount": len(nodemanager.specs),
|
"slavecount": len(nodemanager.specs),
|
||||||
|
"mainargv": sys.argv,
|
||||||
}
|
}
|
||||||
# TODO: deprecated name, backward compatibility only. Remove it in future
|
# TODO: deprecated name, backward compatibility only. Remove it in future
|
||||||
self.slaveinput = self.workerinput
|
self.slaveinput = self.workerinput
|
||||||
|
|||||||
Reference in New Issue
Block a user