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
26 changes: 23 additions & 3 deletions Lib/subprocess.py
Original file line number Diff line number Diff line change
Expand Up @@ -232,15 +232,13 @@ def _optim_args_from_interpreter_flags():

def _args_from_interpreter_flags():
"""Return a list of command-line arguments reproducing the current
settings in sys.flags and sys.warnoptions."""
settings in sys.flags, sys.warnoptions and sys._xoptions."""
flag_opt_map = {
'debug': 'd',
# 'inspect': 'i',
# 'interactive': 'i',
'dont_write_bytecode': 'B',
'no_user_site': 's',
'no_site': 'S',
'ignore_environment': 'E',
'verbose': 'v',
'bytes_warning': 'b',
'quiet': 'q',
Expand All @@ -251,8 +249,30 @@ def _args_from_interpreter_flags():
v = getattr(sys.flags, flag)
if v > 0:
args.append('-' + opt * v)

if sys.flags.isolated:
args.append('-I')
else:
if sys.flags.ignore_environment:
args.append('-E')
if sys.flags.no_user_site:
args.append('-s')

for opt in sys.warnoptions:
args.append('-W' + opt)

# -X options
xoptions = getattr(sys, '_xoptions', {})
for opt in ('faulthandler', 'tracemalloc',
'showalloccount', 'showrefcount', 'utf8'):
if opt in xoptions:
value = xoptions[opt]
if value is True:
arg = opt
else:
arg = '%s=%s' % (opt, value)
args.extend(('-X', arg))

return args


Expand Down
69 changes: 64 additions & 5 deletions Lib/test/test_support.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
import errno
import importlib
import os
import shutil
import socket
import stat
import subprocess
import sys
import os
import unittest
import socket
import tempfile
import textwrap
import errno
import unittest
from test import support
from test.support import script_helper

Expand Down Expand Up @@ -394,6 +395,65 @@ def test_check__all__(self):

self.assertRaises(AssertionError, support.check__all__, self, unittest)

def check_options(self, args, func, expected=None):
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)
if expected is None:
expected = args
self.assertEqual(proc.stdout.rstrip(), repr(expected))
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'],
['-I'],
# same option multiple times
['-bb'],
['-vvv'],
# -W options
['-Wignore'],
# -X options
['-X', 'faulthandler'],
['-X', 'showalloccount'],
['-X', 'showrefcount'],
['-X', 'tracemalloc'],
['-X', 'tracemalloc=3'],
):
with self.subTest(opts=opts):
self.check_options(opts, 'args_from_interpreter_flags')

self.check_options(['-I', '-E', '-s'], 'args_from_interpreter_flags',
['-I'])

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')

def test_match_test(self):
class Test:
def __init__(self, test_id):
Expand Down Expand Up @@ -485,7 +545,6 @@ def test_fd_count(self):
# reap_threads
# reap_children
# strip_python_stderr
# args_from_interpreter_flags
# can_symlink
# skip_unless_symlink
# SuppressCrashReport
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
The :option:`-I` command line option (run Python in isolated mode) is now
also copied by the :mod:`multiprocessing` and :mod:`distutils` modules when
spawning child processes. Previously, only :option:`-E` and :option:`-s` options
(enabled by :option:`-I`) were copied.