diff --git a/Doc/whatsnew/3.8.rst b/Doc/whatsnew/3.8.rst index 6bc131419ca87c..9814c808eb883f 100644 --- a/Doc/whatsnew/3.8.rst +++ b/Doc/whatsnew/3.8.rst @@ -317,14 +317,13 @@ xml Optimizations ============= -* The :mod:`subprocess` module can now use the :func:`os.posix_spawn` function +* The :mod:`subprocess` module can now use the :func:`os.posix_spawnp` function in some cases for better performance. Currently, it is only used on macOS and Linux (using glibc 2.24 or newer) if all these conditions are met: * *close_fds* is false; * *preexec_fn*, *pass_fds*, *cwd* and *start_new_session* parameters - are not set; - * the *executable* path contains a directory. + are not set. * :func:`shutil.copyfile`, :func:`shutil.copy`, :func:`shutil.copy2`, :func:`shutil.copytree` and :func:`shutil.move` use platform-specific diff --git a/Lib/subprocess.py b/Lib/subprocess.py index 0496b447e8ea03..97766b262e068d 100644 --- a/Lib/subprocess.py +++ b/Lib/subprocess.py @@ -607,10 +607,10 @@ def getoutput(cmd): return getstatusoutput(cmd)[1] -def _use_posix_spawn(): - """Check if posix_spawn() can be used for subprocess. +def _use_posix_spawnp(): + """Check if posix_spawnp() can be used for subprocess. - subprocess requires a posix_spawn() implementation that properly reports + subprocess requires a posix_spawnp() implementation that properly reports errors to the parent process, & sets errno on the following failures: * Process attribute actions failed. @@ -620,12 +620,12 @@ def _use_posix_spawn(): Prefer an implementation which can use vfork() in some cases for best performance. """ - if _mswindows or not hasattr(os, 'posix_spawn'): - # os.posix_spawn() is not available + if _mswindows or not hasattr(os, 'posix_spawnp'): + # os.posix_spawnp() is not available return False if sys.platform == 'darwin': - # posix_spawn() is a syscall on macOS and properly reports errors + # posix_spawnp() is a syscall on macOS and properly reports errors return True # Check libc name and runtime libc version @@ -640,8 +640,6 @@ def _use_posix_spawn(): version = tuple(map(int, parts[1].split('.'))) if sys.platform == 'linux' and libc == 'glibc' and version >= (2, 24): - # glibc 2.24 has a new Linux posix_spawn implementation using vfork - # which properly reports errors to the parent process. return True # Note: Don't use the implementation in earlier glibc because it doesn't # use vfork (even if glibc 2.26 added a pipe to properly report errors @@ -650,11 +648,11 @@ def _use_posix_spawn(): # os.confstr() or CS_GNU_LIBC_VERSION value not available pass - # By default, assume that posix_spawn() does not properly report errors. + # By default, assume that posix_spawnp() does not properly report errors. return False -_USE_POSIX_SPAWN = _use_posix_spawn() +_USE_POSIX_SPAWNP = _use_posix_spawnp() class Popen(object): @@ -1461,11 +1459,11 @@ def _get_handles(self, stdin, stdout, stderr): errread, errwrite) - def _posix_spawn(self, args, executable, env, restore_signals, + def _posix_spawnp(self, args, executable, env, restore_signals, p2cread, p2cwrite, c2pread, c2pwrite, errread, errwrite): - """Execute program using os.posix_spawn().""" + """Execute program using os.posix_spawnp().""" if env is None: env = os.environ @@ -1493,7 +1491,7 @@ def _posix_spawn(self, args, executable, env, restore_signals, if file_actions: kwargs['file_actions'] = file_actions - self.pid = os.posix_spawn(executable, args, env, **kwargs) + self.pid = os.posix_spawnp(executable, args, env, **kwargs) self._child_created = True self._close_pipe_fds(p2cread, p2cwrite, @@ -1525,8 +1523,7 @@ def _execute_child(self, args, executable, preexec_fn, close_fds, if executable is None: executable = args[0] - if (_USE_POSIX_SPAWN - and os.path.dirname(executable) + if (_USE_POSIX_SPAWNP and preexec_fn is None and not close_fds and not pass_fds @@ -1535,10 +1532,8 @@ def _execute_child(self, args, executable, preexec_fn, close_fds, and (c2pwrite == -1 or c2pwrite > 2) and (errwrite == -1 or errwrite > 2) and not start_new_session): - self._posix_spawn(args, executable, env, restore_signals, - p2cread, p2cwrite, - c2pread, c2pwrite, - errread, errwrite) + self._posix_spawnp(args, executable, env, restore_signals, p2cread, + p2cwrite, c2pread, c2pwrite, errread, errwrite) return orig_executable = executable diff --git a/Misc/NEWS.d/next/Library/2019-02-18-12-45-33.bpo-35537.xshtGJ.rst b/Misc/NEWS.d/next/Library/2019-02-18-12-45-33.bpo-35537.xshtGJ.rst new file mode 100644 index 00000000000000..75b327d9c45c3e --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-02-18-12-45-33.bpo-35537.xshtGJ.rst @@ -0,0 +1 @@ +The :mod:`subprocess` now uses :func:`os.posix_spawnp` instead of :func:`os.posix_spawn` \ No newline at end of file