From: Géry Ogam Date: Fri, 22 Apr 2022 22:47:09 +0000 (+0200) Subject: bpo-46720: Add support for path-like objects to multiprocessing.set_executable for... X-Git-Tag: v3.11.0b1~242 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=5576ddbbbc9c1d7a7819abc961e5d604ae0f7dd7;p=thirdparty%2FPython%2Fcpython.git bpo-46720: Add support for path-like objects to multiprocessing.set_executable for Windows (GH-31279) This bring the API to be on a par with Unix-like systems. --- diff --git a/Doc/library/multiprocessing.rst b/Doc/library/multiprocessing.rst index 83aa5cb87f49..70802ee1fdec 100644 --- a/Doc/library/multiprocessing.rst +++ b/Doc/library/multiprocessing.rst @@ -1075,6 +1075,9 @@ Miscellaneous .. versionchanged:: 3.4 Now supported on Unix when the ``'spawn'`` start method is used. + .. versionchanged:: 3.11 + Accepts a :term:`path-like object`. + .. function:: set_start_method(method) Set the method which should be used to start child processes. diff --git a/Lib/multiprocessing/spawn.py b/Lib/multiprocessing/spawn.py index 7cc129e26107..09f8a229d7cc 100644 --- a/Lib/multiprocessing/spawn.py +++ b/Lib/multiprocessing/spawn.py @@ -33,18 +33,21 @@ else: WINEXE = getattr(sys, 'frozen', False) WINSERVICE = sys.executable.lower().endswith("pythonservice.exe") -if WINSERVICE: - _python_exe = os.path.join(sys.exec_prefix, 'python.exe') -else: - _python_exe = sys.executable - def set_executable(exe): global _python_exe - _python_exe = exe + if sys.platform == 'win32': + _python_exe = os.fsdecode(exe) + else: + _python_exe = os.fsencode(exe) def get_executable(): return _python_exe +if WINSERVICE: + set_executable(os.path.join(sys.exec_prefix, 'python.exe')) +else: + set_executable(sys.executable) + # # # @@ -86,7 +89,8 @@ def get_command_line(**kwds): prog = 'from multiprocessing.spawn import spawn_main; spawn_main(%s)' prog %= ', '.join('%s=%r' % item for item in kwds.items()) opts = util._args_from_interpreter_flags() - return [_python_exe] + opts + ['-c', prog, '--multiprocessing-fork'] + exe = get_executable() + return [exe] + opts + ['-c', prog, '--multiprocessing-fork'] def spawn_main(pipe_handle, parent_pid=None, tracker_fd=None): diff --git a/Lib/multiprocessing/util.py b/Lib/multiprocessing/util.py index a4683339820f..abbc4c5e6088 100644 --- a/Lib/multiprocessing/util.py +++ b/Lib/multiprocessing/util.py @@ -450,7 +450,7 @@ def spawnv_passfds(path, args, passfds): errpipe_read, errpipe_write = os.pipe() try: return _posixsubprocess.fork_exec( - args, [os.fsencode(path)], True, passfds, None, None, + args, [path], True, passfds, None, None, -1, -1, -1, -1, -1, -1, errpipe_read, errpipe_write, False, False, None, None, None, -1, None) finally: diff --git a/Lib/test/_test_multiprocessing.py b/Lib/test/_test_multiprocessing.py index 427fc0c47a3c..67bb17c0ede3 100644 --- a/Lib/test/_test_multiprocessing.py +++ b/Lib/test/_test_multiprocessing.py @@ -20,6 +20,7 @@ import logging import subprocess import struct import operator +import pathlib import pickle import weakref import warnings @@ -256,6 +257,21 @@ class _TestProcess(BaseTestCase): self.assertEqual(current.ident, os.getpid()) self.assertEqual(current.exitcode, None) + def test_set_executable(self): + if self.TYPE == 'threads': + self.skipTest(f'test not appropriate for {self.TYPE}') + paths = [ + sys.executable, # str + sys.executable.encode(), # bytes + pathlib.Path(sys.executable) # os.PathLike + ] + for path in paths: + self.set_executable(path) + p = self.Process() + p.start() + p.join() + self.assertEqual(p.exitcode, 0) + def test_args_argument(self): # bpo-45735: Using list or tuple as *args* in constructor could # achieve the same effect. @@ -5787,6 +5803,7 @@ class ProcessesMixin(BaseMixin): current_process = staticmethod(multiprocessing.current_process) parent_process = staticmethod(multiprocessing.parent_process) active_children = staticmethod(multiprocessing.active_children) + set_executable = staticmethod(multiprocessing.set_executable) Pool = staticmethod(multiprocessing.Pool) Pipe = staticmethod(multiprocessing.Pipe) Queue = staticmethod(multiprocessing.Queue) diff --git a/Misc/NEWS.d/next/Library/2022-02-11-23-11-35.bpo-46720.nY8spB.rst b/Misc/NEWS.d/next/Library/2022-02-11-23-11-35.bpo-46720.nY8spB.rst new file mode 100644 index 000000000000..70d5e5ef3433 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-02-11-23-11-35.bpo-46720.nY8spB.rst @@ -0,0 +1,2 @@ +Add support for path-like objects to :func:`multiprocessing.set_executable` for +Windows to be on a par with Unix-like systems. Patch by Géry Ogam.