Skip to content

Commit 8c65254

Browse files
freakboy3742aisk
authored andcommitted
pythongh-112736: Refactor del-safe symbol handling in subprocess (python#112738)
Refactor delete-safe symbol handling in subprocess. Only module globals are force-cleared during interpreter finalization, using a class reference instead of individually listing the constants everywhere is simpler.
1 parent 859f988 commit 8c65254

File tree

2 files changed

+25
-24
lines changed

2 files changed

+25
-24
lines changed

Lib/subprocess.py

+24-24
Original file line numberDiff line numberDiff line change
@@ -74,8 +74,8 @@
7474
else:
7575
_mswindows = True
7676

77-
# wasm32-emscripten and wasm32-wasi do not support processes
78-
_can_fork_exec = sys.platform not in {"emscripten", "wasi"}
77+
# some platforms do not support subprocesses
78+
_can_fork_exec = sys.platform not in {"emscripten", "wasi", "ios", "tvos", "watchos"}
7979

8080
if _mswindows:
8181
import _winapi
@@ -103,18 +103,22 @@
103103
if _can_fork_exec:
104104
from _posixsubprocess import fork_exec as _fork_exec
105105
# used in methods that are called by __del__
106-
_waitpid = os.waitpid
107-
_waitstatus_to_exitcode = os.waitstatus_to_exitcode
108-
_WIFSTOPPED = os.WIFSTOPPED
109-
_WSTOPSIG = os.WSTOPSIG
110-
_WNOHANG = os.WNOHANG
106+
class _del_safe:
107+
waitpid = os.waitpid
108+
waitstatus_to_exitcode = os.waitstatus_to_exitcode
109+
WIFSTOPPED = os.WIFSTOPPED
110+
WSTOPSIG = os.WSTOPSIG
111+
WNOHANG = os.WNOHANG
112+
ECHILD = errno.ECHILD
111113
else:
112-
_fork_exec = None
113-
_waitpid = None
114-
_waitstatus_to_exitcode = None
115-
_WIFSTOPPED = None
116-
_WSTOPSIG = None
117-
_WNOHANG = None
114+
class _del_safe:
115+
waitpid = None
116+
waitstatus_to_exitcode = None
117+
WIFSTOPPED = None
118+
WSTOPSIG = None
119+
WNOHANG = None
120+
ECHILD = errno.ECHILD
121+
118122
import select
119123
import selectors
120124

@@ -1951,20 +1955,16 @@ def _execute_child(self, args, executable, preexec_fn, close_fds,
19511955
raise child_exception_type(err_msg)
19521956

19531957

1954-
def _handle_exitstatus(self, sts,
1955-
_waitstatus_to_exitcode=_waitstatus_to_exitcode,
1956-
_WIFSTOPPED=_WIFSTOPPED,
1957-
_WSTOPSIG=_WSTOPSIG):
1958+
def _handle_exitstatus(self, sts, _del_safe=_del_safe):
19581959
"""All callers to this function MUST hold self._waitpid_lock."""
19591960
# This method is called (indirectly) by __del__, so it cannot
19601961
# refer to anything outside of its local scope.
1961-
if _WIFSTOPPED(sts):
1962-
self.returncode = -_WSTOPSIG(sts)
1962+
if _del_safe.WIFSTOPPED(sts):
1963+
self.returncode = -_del_safe.WSTOPSIG(sts)
19631964
else:
1964-
self.returncode = _waitstatus_to_exitcode(sts)
1965+
self.returncode = _del_safe.waitstatus_to_exitcode(sts)
19651966

1966-
def _internal_poll(self, _deadstate=None, _waitpid=_waitpid,
1967-
_WNOHANG=_WNOHANG, _ECHILD=errno.ECHILD):
1967+
def _internal_poll(self, _deadstate=None, _del_safe=_del_safe):
19681968
"""Check if child process has terminated. Returns returncode
19691969
attribute.
19701970
@@ -1980,13 +1980,13 @@ def _internal_poll(self, _deadstate=None, _waitpid=_waitpid,
19801980
try:
19811981
if self.returncode is not None:
19821982
return self.returncode # Another thread waited.
1983-
pid, sts = _waitpid(self.pid, _WNOHANG)
1983+
pid, sts = _del_safe.waitpid(self.pid, _del_safe.WNOHANG)
19841984
if pid == self.pid:
19851985
self._handle_exitstatus(sts)
19861986
except OSError as e:
19871987
if _deadstate is not None:
19881988
self.returncode = _deadstate
1989-
elif e.errno == _ECHILD:
1989+
elif e.errno == _del_safe.ECHILD:
19901990
# This happens if SIGCLD is set to be ignored or
19911991
# waiting for child processes has otherwise been
19921992
# disabled for our process. This child is dead, we
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
The use of del-safe symbols in ``subprocess`` was refactored to allow for use in cross-platform build environments.

0 commit comments

Comments
 (0)