Skip to content

Commit 31955ea

Browse files
committed
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.
1 parent 5ecbf25 commit 31955ea

File tree

3 files changed

+57
-0
lines changed

3 files changed

+57
-0
lines changed

testing/test_remote.py

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
1+
import os
12
import py
23
import pprint
34
import pytest
5+
import sys
46

57
from xdist.workermanage import WorkerController, unserialize_report
68
from xdist.remote import serialize_report
@@ -397,3 +399,55 @@ def test():
397399
)
398400
result = testdir.runpytest("-n2", "--max-worker-restart=0")
399401
assert result.ret == 0
402+
403+
404+
def test_remote_inner_argv(testdir):
405+
"""Test/document the behavior due to execnet using `python -c`."""
406+
testdir.makepyfile(
407+
"""
408+
import sys
409+
def test():
410+
assert sys.argv == ["-c"]
411+
"""
412+
)
413+
result = testdir.runpytest("-n1")
414+
assert result.ret == 0
415+
416+
417+
def test_remote_usage_prog(testdir):
418+
outer_argv = sys.argv[0]
419+
prog = os.path.basename(outer_argv)
420+
421+
testdir.makeconftest(
422+
"""
423+
import pytest
424+
425+
config_parser = None
426+
427+
@pytest.fixture
428+
def get_config_parser():
429+
return config_parser
430+
431+
def pytest_configure(config):
432+
global config_parser
433+
config_parser = config._parser
434+
"""
435+
)
436+
testdir.makepyfile(
437+
"""
438+
import sys
439+
440+
def test(get_config_parser, request):
441+
get_config_parser._getparser().error("my_usage_error")
442+
443+
assert request.config.workerinput["mainargv"] == {!r}
444+
""".format(
445+
outer_argv
446+
)
447+
)
448+
449+
result = testdir.runpytest_subprocess("-n1")
450+
assert result.ret == 1
451+
result.stdout.fnmatch_lines(
452+
["usage: %s *" % prog, "%s: error: my_usage_error" % prog]
453+
)

xdist/remote.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -261,6 +261,7 @@ def remote_initconfig(option_dict, args):
261261
import py
262262

263263
config = remote_initconfig(option_dict, args)
264+
config._parser.prog = os.path.basename(workerinput["mainargv"][0])
264265
config.workerinput = workerinput
265266
config.workeroutput = {}
266267
# TODO: deprecated name, backward compatibility only. Remove it in future

xdist/workermanage.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
import fnmatch
33
import os
44
import re
5+
import sys
56
import threading
67

78
import py
@@ -213,6 +214,7 @@ def __init__(self, nodemanager, gateway, config, putevent):
213214
"workercount": len(nodemanager.specs),
214215
"slaveid": gateway.id,
215216
"slavecount": len(nodemanager.specs),
217+
"mainargv": sys.argv,
216218
}
217219
# TODO: deprecated name, backward compatibility only. Remove it in future
218220
self.slaveinput = self.workerinput

0 commit comments

Comments
 (0)