[Python-checkins] bpo-8110: Refactor platform detection in subprocess (GH-9053)

Zachary Ware webhook-mailer at python.org
Mon Sep 10 19:16:12 EDT 2018


https://github.com/python/cpython/commit/880d42a3b247306f67837aa95e23f7c3471a30a3
commit: 880d42a3b247306f67837aa95e23f7c3471a30a3
branch: master
author: Zachary Ware <zachary.ware at gmail.com>
committer: GitHub <noreply at github.com>
date: 2018-09-10T16:16:08-07:00
summary:

bpo-8110: Refactor platform detection in subprocess (GH-9053)

Check for functionality via imports rather than checking sys.platform
specifically for Windows

files:
A Misc/NEWS.d/next/Library/2018-09-03-23-54-35.bpo-8110.FExWI_.rst
M Lib/subprocess.py

diff --git a/Lib/subprocess.py b/Lib/subprocess.py
index e070011d980e..1e04d5e57013 100644
--- a/Lib/subprocess.py
+++ b/Lib/subprocess.py
@@ -41,18 +41,56 @@
     then returns a (exitcode, output) tuple
 """
 
-import sys
-_mswindows = (sys.platform == "win32")
-
+import builtins
+import errno
 import io
 import os
 import time
 import signal
-import builtins
+import sys
+import threading
 import warnings
-import errno
 from time import monotonic as _time
 
+
+__all__ = ["Popen", "PIPE", "STDOUT", "call", "check_call", "getstatusoutput",
+           "getoutput", "check_output", "run", "CalledProcessError", "DEVNULL",
+           "SubprocessError", "TimeoutExpired", "CompletedProcess"]
+           # NOTE: We intentionally exclude list2cmdline as it is
+           # considered an internal implementation detail.  issue10838.
+
+try:
+    import msvcrt
+    import _winapi
+    _mswindows = True
+except ModuleNotFoundError:
+    _mswindows = False
+    import _posixsubprocess
+    import select
+    import selectors
+else:
+    from _winapi import (CREATE_NEW_CONSOLE, CREATE_NEW_PROCESS_GROUP,
+                         STD_INPUT_HANDLE, STD_OUTPUT_HANDLE,
+                         STD_ERROR_HANDLE, SW_HIDE,
+                         STARTF_USESTDHANDLES, STARTF_USESHOWWINDOW,
+                         ABOVE_NORMAL_PRIORITY_CLASS, BELOW_NORMAL_PRIORITY_CLASS,
+                         HIGH_PRIORITY_CLASS, IDLE_PRIORITY_CLASS,
+                         NORMAL_PRIORITY_CLASS, REALTIME_PRIORITY_CLASS,
+                         CREATE_NO_WINDOW, DETACHED_PROCESS,
+                         CREATE_DEFAULT_ERROR_MODE, CREATE_BREAKAWAY_FROM_JOB)
+
+    __all__.extend(["CREATE_NEW_CONSOLE", "CREATE_NEW_PROCESS_GROUP",
+                    "STD_INPUT_HANDLE", "STD_OUTPUT_HANDLE",
+                    "STD_ERROR_HANDLE", "SW_HIDE",
+                    "STARTF_USESTDHANDLES", "STARTF_USESHOWWINDOW",
+                    "STARTUPINFO",
+                    "ABOVE_NORMAL_PRIORITY_CLASS", "BELOW_NORMAL_PRIORITY_CLASS",
+                    "HIGH_PRIORITY_CLASS", "IDLE_PRIORITY_CLASS",
+                    "NORMAL_PRIORITY_CLASS", "REALTIME_PRIORITY_CLASS",
+                    "CREATE_NO_WINDOW", "DETACHED_PROCESS",
+                    "CREATE_DEFAULT_ERROR_MODE", "CREATE_BREAKAWAY_FROM_JOB"])
+
+
 # Exception classes used by this module.
 class SubprocessError(Exception): pass
 
@@ -123,9 +161,6 @@ def stdout(self, value):
 
 
 if _mswindows:
-    import threading
-    import msvcrt
-    import _winapi
     class STARTUPINFO:
         def __init__(self, *, dwFlags=0, hStdInput=None, hStdOutput=None,
                      hStdError=None, wShowWindow=0, lpAttributeList=None):
@@ -148,53 +183,6 @@ def copy(self):
                                wShowWindow=self.wShowWindow,
                                lpAttributeList=attr_list)
 
-else:
-    import _posixsubprocess
-    import select
-    import selectors
-    import threading
-
-    # When select or poll has indicated that the file is writable,
-    # we can write up to _PIPE_BUF bytes without risk of blocking.
-    # POSIX defines PIPE_BUF as >= 512.
-    _PIPE_BUF = getattr(select, 'PIPE_BUF', 512)
-
-    # poll/select have the advantage of not requiring any extra file
-    # descriptor, contrarily to epoll/kqueue (also, they require a single
-    # syscall).
-    if hasattr(selectors, 'PollSelector'):
-        _PopenSelector = selectors.PollSelector
-    else:
-        _PopenSelector = selectors.SelectSelector
-
-
-__all__ = ["Popen", "PIPE", "STDOUT", "call", "check_call", "getstatusoutput",
-           "getoutput", "check_output", "run", "CalledProcessError", "DEVNULL",
-           "SubprocessError", "TimeoutExpired", "CompletedProcess"]
-           # NOTE: We intentionally exclude list2cmdline as it is
-           # considered an internal implementation detail.  issue10838.
-
-if _mswindows:
-    from _winapi import (CREATE_NEW_CONSOLE, CREATE_NEW_PROCESS_GROUP,
-                         STD_INPUT_HANDLE, STD_OUTPUT_HANDLE,
-                         STD_ERROR_HANDLE, SW_HIDE,
-                         STARTF_USESTDHANDLES, STARTF_USESHOWWINDOW,
-                         ABOVE_NORMAL_PRIORITY_CLASS, BELOW_NORMAL_PRIORITY_CLASS,
-                         HIGH_PRIORITY_CLASS, IDLE_PRIORITY_CLASS,
-                         NORMAL_PRIORITY_CLASS, REALTIME_PRIORITY_CLASS,
-                         CREATE_NO_WINDOW, DETACHED_PROCESS,
-                         CREATE_DEFAULT_ERROR_MODE, CREATE_BREAKAWAY_FROM_JOB)
-
-    __all__.extend(["CREATE_NEW_CONSOLE", "CREATE_NEW_PROCESS_GROUP",
-                    "STD_INPUT_HANDLE", "STD_OUTPUT_HANDLE",
-                    "STD_ERROR_HANDLE", "SW_HIDE",
-                    "STARTF_USESTDHANDLES", "STARTF_USESHOWWINDOW",
-                    "STARTUPINFO",
-                    "ABOVE_NORMAL_PRIORITY_CLASS", "BELOW_NORMAL_PRIORITY_CLASS",
-                    "HIGH_PRIORITY_CLASS", "IDLE_PRIORITY_CLASS",
-                    "NORMAL_PRIORITY_CLASS", "REALTIME_PRIORITY_CLASS",
-                    "CREATE_NO_WINDOW", "DETACHED_PROCESS",
-                    "CREATE_DEFAULT_ERROR_MODE", "CREATE_BREAKAWAY_FROM_JOB"])
 
     class Handle(int):
         closed = False
@@ -215,6 +203,19 @@ def __repr__(self):
 
         __del__ = Close
         __str__ = __repr__
+else:
+    # When select or poll has indicated that the file is writable,
+    # we can write up to _PIPE_BUF bytes without risk of blocking.
+    # POSIX defines PIPE_BUF as >= 512.
+    _PIPE_BUF = getattr(select, 'PIPE_BUF', 512)
+
+    # poll/select have the advantage of not requiring any extra file
+    # descriptor, contrarily to epoll/kqueue (also, they require a single
+    # syscall).
+    if hasattr(selectors, 'PollSelector'):
+        _PopenSelector = selectors.PollSelector
+    else:
+        _PopenSelector = selectors.SelectSelector
 
 
 # This lists holds Popen instances for which the underlying process had not
diff --git a/Misc/NEWS.d/next/Library/2018-09-03-23-54-35.bpo-8110.FExWI_.rst b/Misc/NEWS.d/next/Library/2018-09-03-23-54-35.bpo-8110.FExWI_.rst
new file mode 100644
index 000000000000..c29ace1a0fc6
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2018-09-03-23-54-35.bpo-8110.FExWI_.rst
@@ -0,0 +1,2 @@
+Refactored :mod:`subprocess` to check for Windows-specific modules rather
+than ``sys.platform == 'win32'``.



More information about the Python-checkins mailing list