summaryrefslogtreecommitdiffstats
path: root/setup.py
diff options
context:
space:
mode:
authorVictor Stinner <vstinner@python.org>2020-03-04 13:50:19 (GMT)
committerGitHub <noreply@github.com>2020-03-04 13:50:19 (GMT)
commit1ec63b62035e73111e204a0e03b83503e1c58f2e (patch)
tree1f21da1148b4b09981c49f900adf9194930e62e4 /setup.py
parentdffe4c07095e0c693e094d3c140e85a68bd8128e (diff)
downloadcpython-1ec63b62035e73111e204a0e03b83503e1c58f2e.zip
cpython-1ec63b62035e73111e204a0e03b83503e1c58f2e.tar.gz
cpython-1ec63b62035e73111e204a0e03b83503e1c58f2e.tar.bz2
bpo-39763: distutils.spawn now uses subprocess (GH-18743)
Reimplement distutils.spawn.spawn() function with the subprocess module. setup.py now uses a basic implementation of the subprocess module if the subprocess module is not available: before required C extension modules are built.
Diffstat (limited to 'setup.py')
-rw-r--r--setup.py60
1 files changed, 60 insertions, 0 deletions
diff --git a/setup.py b/setup.py
index 51e67fe..c9f3c97 100644
--- a/setup.py
+++ b/setup.py
@@ -10,6 +10,61 @@ import sys
import sysconfig
from glob import glob
+
+try:
+ import subprocess
+ del subprocess
+ SUBPROCESS_BOOTSTRAP = False
+except ImportError:
+ SUBPROCESS_BOOTSTRAP = True
+
+ # Bootstrap Python: distutils.spawn uses subprocess to build C extensions,
+ # subprocess requires C extensions built by setup.py like _posixsubprocess.
+ #
+ # Basic subprocess implementation for POSIX (setup.py is not used on
+ # Windows) which only uses os functions. Only implement features required
+ # by distutils.spawn.
+ #
+ # It is dropped from sys.modules as soon as all C extension modules
+ # are built.
+ class Popen:
+ def __init__(self, cmd, env=None):
+ self._cmd = cmd
+ self._env = env
+ self.returncode = None
+
+ def wait(self):
+ pid = os.fork()
+ if pid == 0:
+ # Child process
+ try:
+ if self._env is not None:
+ os.execve(self._cmd[0], self._cmd, self._env)
+ else:
+ os.execv(self._cmd[0], self._cmd)
+ finally:
+ os._exit(1)
+ else:
+ # Parent process
+ pid, status = os.waitpid(pid, 0)
+ if os.WIFSIGNALED(status):
+ self.returncode = -os.WTERMSIG(status)
+ elif os.WIFEXITED(status):
+ self.returncode = os.WEXITSTATUS(status)
+ elif os.WIFSTOPPED(status):
+ self.returncode = -os.WSTOPSIG(sts)
+ else:
+ # Should never happen
+ raise Exception("Unknown child exit status!")
+
+ return self.returncode
+
+ mod = type(sys)('subprocess')
+ mod.Popen = Popen
+ sys.modules['subprocess'] = mod
+ del mod
+
+
from distutils import log
from distutils.command.build_ext import build_ext
from distutils.command.build_scripts import build_scripts
@@ -391,6 +446,11 @@ class PyBuildExt(build_ext):
build_ext.build_extensions(self)
+ if SUBPROCESS_BOOTSTRAP:
+ # Drop our custom subprocess module:
+ # use the newly built subprocess module
+ del sys.modules['subprocess']
+
for ext in self.extensions:
self.check_extension_import(ext)