From 77c84f2defb0013e28d262be237142379a1407fe Mon Sep 17 00:00:00 2001 From: Richard Oudkerk Date: Fri, 18 May 2012 14:28:02 +0100 Subject: #12098: Make multiprocessing's child processes inherit sys.flags on Windows Initial patch by Sergey Mezentsev. --- Lib/multiprocessing/forking.py | 3 ++- Lib/multiprocessing/util.py | 31 +++++++++++++++++++++++++++++++ Lib/test/support.py | 20 ++------------------ Lib/test/test_multiprocessing.py | 35 ++++++++++++++++++++++++++++++++++- Misc/NEWS | 4 ++++ 5 files changed, 73 insertions(+), 20 deletions(-) diff --git a/Lib/multiprocessing/forking.py b/Lib/multiprocessing/forking.py index 2729afe..eadc321 100644 --- a/Lib/multiprocessing/forking.py +++ b/Lib/multiprocessing/forking.py @@ -324,7 +324,8 @@ else: return [sys.executable, '--multiprocessing-fork'] else: prog = 'from multiprocessing.forking import main; main()' - return [_python_exe, '-c', prog, '--multiprocessing-fork'] + opts = util._args_from_interpreter_flags() + return [_python_exe] + opts + ['-c', prog, '--multiprocessing-fork'] def main(): diff --git a/Lib/multiprocessing/util.py b/Lib/multiprocessing/util.py index 9b6dac2..7c71081 100644 --- a/Lib/multiprocessing/util.py +++ b/Lib/multiprocessing/util.py @@ -7,6 +7,7 @@ # Licensed to PSF under a Contributor Agreement. # +import sys import functools import itertools import weakref @@ -295,3 +296,33 @@ class ForkAwareLocal(threading.local): register_after_fork(self, lambda obj : obj.__dict__.clear()) def __reduce__(self): return type(self), () + +# +# Get options for python to produce the same sys.flags +# + +def _args_from_interpreter_flags(): + """Return a list of command-line arguments reproducing the current + settings in sys.flags and sys.warnoptions.""" + flag_opt_map = { + 'debug': 'd', + # 'inspect': 'i', + # 'interactive': 'i', + 'optimize': 'O', + 'dont_write_bytecode': 'B', + 'no_user_site': 's', + 'no_site': 'S', + 'ignore_environment': 'E', + 'verbose': 'v', + 'bytes_warning': 'b', + 'quiet': 'q', + 'hash_randomization': 'R', + } + args = [] + for flag, opt in flag_opt_map.items(): + v = getattr(sys.flags, flag) + if v > 0: + args.append('-' + opt * v) + for opt in sys.warnoptions: + args.append('-W' + opt) + return args diff --git a/Lib/test/support.py b/Lib/test/support.py index 4568e54..5259e27 100644 --- a/Lib/test/support.py +++ b/Lib/test/support.py @@ -1596,24 +1596,8 @@ def strip_python_stderr(stderr): def args_from_interpreter_flags(): """Return a list of command-line arguments reproducing the current settings in sys.flags and sys.warnoptions.""" - flag_opt_map = { - 'bytes_warning': 'b', - 'dont_write_bytecode': 'B', - 'hash_randomization': 'R', - 'ignore_environment': 'E', - 'no_user_site': 's', - 'no_site': 'S', - 'optimize': 'O', - 'verbose': 'v', - } - args = [] - for flag, opt in flag_opt_map.items(): - v = getattr(sys.flags, flag) - if v > 0: - args.append('-' + opt * v) - for opt in sys.warnoptions: - args.append('-W' + opt) - return args + from multiprocessing.util import _args_from_interpreter_flags + return _args_from_interpreter_flags() #============================================================ # Support for assertions about logging. diff --git a/Lib/test/test_multiprocessing.py b/Lib/test/test_multiprocessing.py index d10d51b..f02041e 100644 --- a/Lib/test/test_multiprocessing.py +++ b/Lib/test/test_multiprocessing.py @@ -2814,8 +2814,41 @@ class TestInvalidFamily(unittest.TestCase): with self.assertRaises(ValueError): multiprocessing.connection.Listener('/var/test.pipe') +# +# Issue 12098: check sys.flags of child matches that for parent +# + +class TestFlags(unittest.TestCase): + @classmethod + def run_in_grandchild(cls, conn): + conn.send(tuple(sys.flags)) + + @classmethod + def run_in_child(cls): + import json + r, w = multiprocessing.Pipe(duplex=False) + p = multiprocessing.Process(target=cls.run_in_grandchild, args=(w,)) + p.start() + grandchild_flags = r.recv() + p.join() + r.close() + w.close() + flags = (tuple(sys.flags), grandchild_flags) + print(json.dumps(flags)) + + def test_flags(self): + import json, subprocess + # start child process using unusual flags + prog = ('from test.test_multiprocessing import TestFlags; ' + + 'TestFlags.run_in_child()') + data = subprocess.check_output( + [sys.executable, '-E', '-S', '-O', '-c', prog]) + child_flags, grandchild_flags = json.loads(data.decode('ascii')) + self.assertEqual(child_flags, grandchild_flags) + testcases_other = [OtherTest, TestInvalidHandle, TestInitializers, - TestStdinBadfiledescriptor, TestWait, TestInvalidFamily] + TestStdinBadfiledescriptor, TestWait, TestInvalidFamily, + TestFlags] # # diff --git a/Misc/NEWS b/Misc/NEWS index 3e11956..db88500 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -38,6 +38,10 @@ Core and Builtins Library ------- +- Issue #12098: multiprocessing on Windows now starts child processes + using the same sys.flags as the current process. Initial patch by + Sergey Mezentsev. + - Issue #13031: Small speed-up for tarfile when unzipping tarfiles. Patch by Justin Peel. -- cgit v0.12