mirror of https://github.com/python/cpython
Backport r81155.
This commit is contained in:
parent
ebb5a88fd6
commit
19640500ff
|
@ -675,12 +675,12 @@ class Popen(object):
|
||||||
return data.decode(encoding)
|
return data.decode(encoding)
|
||||||
|
|
||||||
|
|
||||||
def __del__(self, sys=sys):
|
def __del__(self, _maxsize=sys.maxsize, _active=_active):
|
||||||
if not self._child_created:
|
if not self._child_created:
|
||||||
# We didn't get to successfully create a child process.
|
# We didn't get to successfully create a child process.
|
||||||
return
|
return
|
||||||
# In case the child hasn't been waited on, check if it's done.
|
# 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:
|
if self.returncode is None and _active is not None:
|
||||||
# Child is still running, keep us alive until we can wait on it.
|
# Child is still running, keep us alive until we can wait on it.
|
||||||
_active.append(self)
|
_active.append(self)
|
||||||
|
@ -883,13 +883,20 @@ class Popen(object):
|
||||||
errwrite.Close()
|
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
|
"""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 self.returncode is None:
|
||||||
if(_subprocess.WaitForSingleObject(self._handle, 0) ==
|
if _WaitForSingleObject(self._handle, 0) == _WAIT_OBJECT_0:
|
||||||
_subprocess.WAIT_OBJECT_0):
|
self.returncode = _GetExitCodeProcess(self._handle)
|
||||||
self.returncode = _subprocess.GetExitCodeProcess(self._handle)
|
|
||||||
return self.returncode
|
return self.returncode
|
||||||
|
|
||||||
|
|
||||||
|
@ -1150,25 +1157,35 @@ class Popen(object):
|
||||||
raise child_exception
|
raise child_exception
|
||||||
|
|
||||||
|
|
||||||
def _handle_exitstatus(self, sts):
|
def _handle_exitstatus(self, sts, _WIFSIGNALED=os.WIFSIGNALED,
|
||||||
if os.WIFSIGNALED(sts):
|
_WTERMSIG=os.WTERMSIG, _WIFEXITED=os.WIFEXITED,
|
||||||
self.returncode = -os.WTERMSIG(sts)
|
_WEXITSTATUS=os.WEXITSTATUS):
|
||||||
elif os.WIFEXITED(sts):
|
# This method is called (indirectly) by __del__, so it cannot
|
||||||
self.returncode = os.WEXITSTATUS(sts)
|
# refer to anything outside of its local scope."""
|
||||||
|
if _WIFSIGNALED(sts):
|
||||||
|
self.returncode = -_WTERMSIG(sts)
|
||||||
|
elif _WIFEXITED(sts):
|
||||||
|
self.returncode = _WEXITSTATUS(sts)
|
||||||
else:
|
else:
|
||||||
# Should never happen
|
# Should never happen
|
||||||
raise RuntimeError("Unknown child exit status!")
|
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
|
"""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:
|
if self.returncode is None:
|
||||||
try:
|
try:
|
||||||
pid, sts = os.waitpid(self.pid, os.WNOHANG)
|
pid, sts = _waitpid(self.pid, _WNOHANG)
|
||||||
if pid == self.pid:
|
if pid == self.pid:
|
||||||
self._handle_exitstatus(sts)
|
self._handle_exitstatus(sts)
|
||||||
except os.error:
|
except _os_error:
|
||||||
if _deadstate is not None:
|
if _deadstate is not None:
|
||||||
self.returncode = _deadstate
|
self.returncode = _deadstate
|
||||||
return self.returncode
|
return self.returncode
|
||||||
|
|
|
@ -40,6 +40,9 @@ Core and Builtins
|
||||||
Library
|
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
|
- Issue #8681: Make the zlib module's error messages more informative when
|
||||||
the zlib itself doesn't give any detailed explanation.
|
the zlib itself doesn't give any detailed explanation.
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue