Decouple the C compilers from distutils build/filesystem helpers#417
Open
jaraco wants to merge 6 commits into
Open
Decouple the C compilers from distutils build/filesystem helpers#417jaraco wants to merge 6 commits into
jaraco wants to merge 6 commits into
Conversation
Add stdlib-only copies of the generic build helpers the C compilers rely on (spawn, newer/newer_group, split_quoted) as siblings of compilers.logging, so the package can provide them without importing distutils.spawn/_modified/util. Errors still route through distutils.errors pending pypa/setuptools#5270; the macOS deployment env injection still defers to distutils.util pending pypa/setuptools#5268. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Point base/unix/cygwin at compilers.spawn/_modified/_util, and reimplement Compiler.mkpath, move_file, and execute directly on the stdlib (os.makedirs, shutil.move). Inline the cygwin .def-file write (dropping distutils.file_util.write_file and the execute indirection). The public methods are retained for backward compatibility. Ref pypa/setuptools#5267, pypa/setuptools#5264. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The _fallback_spawn guard tolerated third-party spawn overrides that predate the 'env' keyword (numpy.distutils before 1.19, per #15). numpy.distutils has accepted env since then and does not run on Python 3.12+, so the shim now protects essentially nothing. Remove it, narrow Compiler.spawn to spawn(cmd, *, env=None), and trim the vendored primitive to match. Ref pypa/setuptools#5267. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Drop the macOS deployment-target injection (_inject_macos_ver) and the shutil.which PATH resolution. subprocess.check_call searches PATH itself, and the macOS injection only ever mattered for compiler/linker invocations, which now carry it in the compilers package. spawn now just logs the command, forwards cmd and **kwargs to check_call, and maps OSError/CalledProcessError to DistutilsExecError. Command.spawn no longer forwards the now-defunct search_path. Ref pypa/setuptools#5267. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Introduce Compiler.call as the modern subprocess entry point: it logs, injects the macOS deployment target (now compilers.platform.macos._inject_ver, moved out of distutils.spawn), and calls check_call, letting native subprocess exceptions propagate. Compiler.spawn becomes a deprecation shim that translates them to DistutilsExecError (imported late). Internal call sites across unix/cygwin/zos/msvc move to call() and catch subprocess.CalledProcessError/OSError; MSVC's PATH injection moves from a spawn override to a call override. Eliminates the vendored compilers.spawn module. Ref pypa/setuptools#5267. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
jaraco
commented
Jul 26, 2026
| from .._modified import newer_group | ||
| from .._util import split_quoted | ||
| from ..logging import get_logger | ||
| from ..platform.macos import _inject_ver |
Member
Author
There was a problem hiding this comment.
Use from ..platform import macos, so that the macos name is reflected in the call below.
jaraco
commented
Jul 26, 2026
Comment on lines
+1188
to
+1199
| from ...errors import DistutilsExecError | ||
|
|
||
| try: | ||
| self.call(cmd, env=env, **kwargs) | ||
| except OSError as exc: | ||
| raise DistutilsExecError( | ||
| f"command {cmd[0]!r} failed: {exc.args[-1]}" | ||
| ) from exc | ||
| except subprocess.CalledProcessError as err: | ||
| raise DistutilsExecError( | ||
| f"command {cmd[0]!r} failed with exit code {err.returncode}" | ||
| ) from err |
Member
Author
There was a problem hiding this comment.
Let's unify this behavior with distutils.spawn.spawn, either by extracting a context manager to do the exception translation or by having "inner" spawn that's called after the logging is done.
Import the macos module (from ..platform import macos) so the injection reads as macos._inject_ver at the call site. Extract the subprocess -> DistutilsExecError translation into a _translate_errors context manager in distutils.spawn, shared by distutils.spawn.spawn and the deprecated Compiler.spawn (imported late). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Removes the C compilers' dependence on distutils' build/filesystem helpers, per the analysis in pypa/setuptools#5267 (Phase 1 of pypa/setuptools#5264).
What changed
Vendored into the
compilersnamespace package (stdlib-only, siblings of thelogging.pyfrom #5266):compilers/_modified.py—newer/newer_groupmtime helpers.compilers/_util.py—split_quoted, vendored verbatim (a switch toshlex.splitis not behavior-equivalent and is left for later).Subprocess execution reworked into a modern
call+ deprecatedspawn:Compiler.call(cmd, *, env=None, **kwargs)— the modern entry point: logs the command, injects the macOS deployment target, and runssubprocess.check_call, letting nativesubprocessexceptions propagate.Compiler.spawnis now a deprecation shim — it warns, delegates tocall, and translatessubprocess/OSErrorfailures toDistutilsExecError(imported late, to keep the package offdistutils.errorsat module scope).unix/cygwin/zos/msvcmoved tocall()and now catchsubprocess.CalledProcessError/OSError. MSVC's PATH injection moved from aspawnoverride to acalloverride.distutils.spawnintocompilers/platform/macos.py(_inject_ver) — the compiler path is the only place it applies (verified: no non-compilerspawncall site invokes a compiler/linker).compilers/spawn.pyis removed.distutils.spawn.spawnreduced to a thin wrapper — it now only logs, forwardscmd/**kwargstosubprocess.check_call, and mapsOSError/CalledProcessErrortoDistutilsExecError; noshutil.which(subprocess searchesPATHitself) and no macOS injection.Command.spawnno longer forwards the now-defunctsearch_path.Modernized in place — the public
Compilermethods keep their signatures for backward compatibility, but their bodies now use the stdlib:mkpath→os.makedirs(name, mode, exist_ok=True)(empty-name guarded).move_file→shutil.move.execute→ trivial log-and-call, no longer used internally.Eliminated — the cygwin
.def-file write is inlined (pathlib.Path.write_text), removingdistutils.file_util.write_fileand theexecuteindirection. Also removed the MSVC_fallback_spawnmonkeypatch shim (numpy.distutils <1.19, per #15) and its now-dead pytest filter.Net:
compilers/C/*no longer importdistutils.spawn,dir_util,file_util,_modified, orutil.execute/split_quoted.Deliberately out of scope
Two transitive couplings remain, by design, as they belong to sibling sub-issues:
_modified/ deprecatedspawnstill referenceDistutils*Error(nativecompilers.errorsis #5270 / S6);_inject_verstill callsdistutils.utilfor the target-version helpers (platform/util decoupling is #5268 / S4).Verification
call()raises native exceptions without warning;spawn()warns and translates toDistutilsExecError;distutils.spawn.spawnstill translates.ruff check --select F,Iclean on all changed files.🤖 Generated with Claude Code