Description
Bug report
Bug description:
The subprocess module has a number of symbols that must be available during the deletion process. To ensure this, the symbols that must be available for deletion are pre-declared, then used as the default value of arguments of methods. For example, see the handling of _waitstatus_to_exitcode
, _WIFSTOPPED
and _WSTOPSIG
in _handle_exitstatus
.
However, in a cross-platform compilation environment, this poses a problem. The approach taken by cross-platform environments (such as crossenv) is to build a hybrid environment by creating a virtual environment on the build machine, then monkeypatch any standard library module that has platform-specific properties. This allows code to execute using build platform executables, but return properties of the host platform as required.
By binding specific constant values as arguments, those values can't be overwritten by a monkeypatch; e.g.,:
import subprocess
# Mock a disabled waitpid
subprocess._waitpid = None
This won't work, because _waitpid
has already been bound as an argument in the methods that use it when the subprocess module was imported.
Most historical cross platform compilation environments won't be affected by this, as both the build and host platform will support subprocesses, so there either isn't a need to patch the subprocess module, or the constants on the build and host are the same. However, when building a cross-platform build environment for iOS, the build platform supports subprocesses, but iOS doesn't, and there is a need to monkeypatch the delete-safe symbols so that the hybrid environment disables subprocesses.
If the symbols that need to be delete-safe were gathered into a single wrapper object, it would both simplify the process of passing in the delete safe properties (as you only need to bind a single object acting as a namespace), and allow for cross-platform environments to monkeypatch the symbols, as the monkeypatch can modify the properties of the namespace object:
import subprocess
# Mock a disabled waitpid
subprocess._del_safe.waitpid = None
This will work, because _del_safe
is the object that has been bound as an argument, and waitpid
is a property of that object.
CPython versions tested on:
3.13
Operating systems tested on:
Other