[Python-checkins] r81159 - in python/branches/release31-maint: Lib/subprocess.py Misc/NEWS

brett.cannon python-checkins at python.org
Fri May 14 03:28:56 CEST 2010


Author: brett.cannon
Date: Fri May 14 03:28:56 2010
New Revision: 81159

Log:
Backport r81155.

Modified:
   python/branches/release31-maint/Lib/subprocess.py
   python/branches/release31-maint/Misc/NEWS

Modified: python/branches/release31-maint/Lib/subprocess.py
==============================================================================
--- python/branches/release31-maint/Lib/subprocess.py	(original)
+++ python/branches/release31-maint/Lib/subprocess.py	Fri May 14 03:28:56 2010
@@ -675,12 +675,12 @@
         return data.decode(encoding)
 
 
-    def __del__(self, sys=sys):
+    def __del__(self, _maxsize=sys.maxsize, _active=_active):
         if not self._child_created:
             # We didn't get to successfully create a child process.
             return
         # In case the child hasn't been waited on, check if it's done.
-        self._internal_poll(_deadstate=sys.maxsize)
+        self._internal_poll(_deadstate=_maxsize)
         if self.returncode is None and _active is not None:
             # Child is still running, keep us alive until we can wait on it.
             _active.append(self)
@@ -883,13 +883,20 @@
                 errwrite.Close()
 
 
-        def _internal_poll(self, _deadstate=None):
+        def _internal_poll(self, _deadstate=None,
+                _WaitForSingleObject=WaitForSingleObject,
+                _WAIT_OBJECT_0=WAIT_OBJECT_0,
+                _GetExitCodeProcess=GetExitCodeProcess):
             """Check if child process has terminated.  Returns returncode
-            attribute."""
+            attribute.
+
+            This method is called by __del__, so it can only refer to objects
+            in its local scope.
+
+            """
             if self.returncode is None:
-                if(_subprocess.WaitForSingleObject(self._handle, 0) ==
-                   _subprocess.WAIT_OBJECT_0):
-                    self.returncode = _subprocess.GetExitCodeProcess(self._handle)
+                if _WaitForSingleObject(self._handle, 0) == _WAIT_OBJECT_0:
+                    self.returncode = _GetExitCodeProcess(self._handle)
             return self.returncode
 
 
@@ -1150,25 +1157,35 @@
                 raise child_exception
 
 
-        def _handle_exitstatus(self, sts):
-            if os.WIFSIGNALED(sts):
-                self.returncode = -os.WTERMSIG(sts)
-            elif os.WIFEXITED(sts):
-                self.returncode = os.WEXITSTATUS(sts)
+        def _handle_exitstatus(self, sts, _WIFSIGNALED=os.WIFSIGNALED,
+                _WTERMSIG=os.WTERMSIG, _WIFEXITED=os.WIFEXITED,
+                _WEXITSTATUS=os.WEXITSTATUS):
+            # This method is called (indirectly) by __del__, so it cannot
+            # refer to anything outside of its local scope."""
+            if _WIFSIGNALED(sts):
+                self.returncode = -_WTERMSIG(sts)
+            elif _WIFEXITED(sts):
+                self.returncode = _WEXITSTATUS(sts)
             else:
                 # Should never happen
                 raise RuntimeError("Unknown child exit status!")
 
 
-        def _internal_poll(self, _deadstate=None):
+        def _internal_poll(self, _deadstate=None, _waitpid=os.waitpid,
+                _WNOHANG=os.WNOHANG, _os_error=os.error):
             """Check if child process has terminated.  Returns returncode
-            attribute."""
+            attribute.
+
+            This method is called by __del__, so it cannot reference anything
+            outside of the local scope (nor can any methods it calls).
+
+            """
             if self.returncode is None:
                 try:
-                    pid, sts = os.waitpid(self.pid, os.WNOHANG)
+                    pid, sts = _waitpid(self.pid, _WNOHANG)
                     if pid == self.pid:
                         self._handle_exitstatus(sts)
-                except os.error:
+                except _os_error:
                     if _deadstate is not None:
                         self.returncode = _deadstate
             return self.returncode

Modified: python/branches/release31-maint/Misc/NEWS
==============================================================================
--- python/branches/release31-maint/Misc/NEWS	(original)
+++ python/branches/release31-maint/Misc/NEWS	Fri May 14 03:28:56 2010
@@ -40,6 +40,9 @@
 Library
 -------
 
+- Issue #5099: subprocess.Popen.__del__ no longer references global objects
+  to prevent issues during interpreter shutdown.
+
 - Issue #8681: Make the zlib module's error messages more informative when
   the zlib itself doesn't give any detailed explanation.
 


More information about the Python-checkins mailing list