Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 22 additions & 1 deletion Lib/subprocess.py
Original file line number Diff line number Diff line change
Expand Up @@ -260,8 +260,29 @@ def _args_from_interpreter_flags():
v = getattr(sys.flags, flag)
if v > 0:
args.append('-' + opt * v)
for opt in sys.warnoptions:

# -W options
warnoptions = sys.warnoptions
xoptions = getattr(sys, '_xoptions', {})
if 'dev' in xoptions and warnoptions and warnoptions[-1] == 'default':
# special case: -X dev adds 'default' to sys.warnoptions
warnoptions = warnoptions[:-1]
for opt in warnoptions:
args.append('-W' + opt)

# -X options
if 'dev' in xoptions:
args.extend(('-X', 'dev'))
for opt in ('faulthandler', 'tracemalloc', 'importtime',
'showalloccount', 'showrefcount'):
if opt in xoptions:
value = xoptions[opt]
if value is True:
arg = opt
else:
arg = '%s=%s' % (opt, value)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you want to use a pretty f-string here?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nope, I prefer to use str % args here :-) Don't ask me why, I have no rationale for such coding style choice :-)

args.extend(('-X', arg))

return args


Expand Down
58 changes: 57 additions & 1 deletion Lib/test/test_support.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import shutil
import socket
import stat
import subprocess
import sys
import tempfile
import time
Expand Down Expand Up @@ -426,6 +427,62 @@ def test_reap_children(self):
# pending child process
support.reap_children()

def check_options(self, args, func):
code = f'from test.support import {func}; print(repr({func}()))'
cmd = [sys.executable, *args, '-c', code]
env = {key: value for key, value in os.environ.items()
if not key.startswith('PYTHON')}
proc = subprocess.run(cmd,
stdout=subprocess.PIPE,
stderr=subprocess.DEVNULL,
universal_newlines=True,
env=env)
self.assertEqual(proc.stdout.rstrip(), repr(args))
self.assertEqual(proc.returncode, 0)

def test_args_from_interpreter_flags(self):
# Test test.support.args_from_interpreter_flags()
for opts in (
# no option
[],
# single option
['-B'],
['-s'],
['-S'],
['-E'],
['-v'],
['-b'],
['-q'],
# same option multiple times
['-bb'],
['-vvv'],
# -W options
['-Wignore'],
# -X options
['-X', 'dev'],
['-Wignore', '-X', 'dev'],
['-X', 'faulthandler'],
['-X', 'importtime'],
['-X', 'showalloccount'],
['-X', 'showrefcount'],
['-X', 'tracemalloc'],
['-X', 'tracemalloc=3'],
):
with self.subTest(opts=opts):
self.check_options(opts, 'args_from_interpreter_flags')

def test_optim_args_from_interpreter_flags(self):
# Test test.support.optim_args_from_interpreter_flags()
for opts in (
# no option
[],
['-O'],
['-OO'],
['-OOOO'],
):
with self.subTest(opts=opts):
self.check_options(opts, 'optim_args_from_interpreter_flags')

# XXX -follows a list of untested API
# make_legacy_pyc
# is_resource_enabled
Expand All @@ -447,7 +504,6 @@ def test_reap_children(self):
# threading_cleanup
# reap_threads
# strip_python_stderr
# args_from_interpreter_flags
# can_symlink
# skip_unless_symlink
# SuppressCrashReport
Expand Down