From 8553db593975b9cfed7ed7351ff63b7ec295412f Mon Sep 17 00:00:00 2001 From: Avasam Date: Sat, 20 Dec 2025 00:53:35 -0500 Subject: [PATCH] `spawn`: don't force param `cmd` to be mutable --- distutils/cmd.py | 13 ++++++++++--- distutils/compilers/C/base.py | 14 ++++---------- distutils/compilers/C/msvc.py | 19 ++++++++++++------- distutils/spawn.py | 15 ++++++++++++--- 4 files changed, 38 insertions(+), 23 deletions(-) diff --git a/distutils/cmd.py b/distutils/cmd.py index 9054783d..bd31b129 100644 --- a/distutils/cmd.py +++ b/distutils/cmd.py @@ -11,8 +11,15 @@ import re import sys from abc import abstractmethod -from collections.abc import Callable, MutableSequence -from typing import TYPE_CHECKING, Any, ClassVar, TypeVar, cast, overload +from collections.abc import Callable, Sequence +from typing import ( + TYPE_CHECKING, + Any, + ClassVar, + TypeVar, + cast, + overload, +) from . import _modified, archive_util, dir_util, file_util, util from ._log import log @@ -451,7 +458,7 @@ def move_file( return file_util.move_file(src, dst) def spawn( - self, cmd: MutableSequence[str], search_path: bool = True, level: int = 1 + self, cmd: Sequence[bytes | os.PathLike[bytes] | str | os.PathLike[str]] ) -> None: """Spawn an external command respecting dry-run flag.""" from distutils.spawn import spawn diff --git a/distutils/compilers/C/base.py b/distutils/compilers/C/base.py index acb9d96b..0a489c14 100644 --- a/distutils/compilers/C/base.py +++ b/distutils/compilers/C/base.py @@ -12,14 +12,8 @@ import subprocess import sys import warnings -from collections.abc import Callable, Iterable, MutableSequence, Sequence -from typing import ( - TYPE_CHECKING, - ClassVar, - Literal, - TypeVar, - overload, -) +from collections.abc import Callable, Iterable, Sequence +from typing import TYPE_CHECKING, ClassVar, Literal, TypeVar, overload from more_itertools import always_iterable @@ -1167,7 +1161,7 @@ def execute( def call( self, - cmd: MutableSequence[bytes | str | os.PathLike[str]], + cmd: Sequence[bytes | os.PathLike[bytes] | str | os.PathLike[str]], *, env: _ENV | None = None, **kwargs, @@ -1178,7 +1172,7 @@ def call( def spawn( self, - cmd: MutableSequence[bytes | str | os.PathLike[str]], + cmd: Sequence[bytes | os.PathLike[bytes] | str | os.PathLike[str]], *, env: _ENV | None = None, **kwargs, diff --git a/distutils/compilers/C/msvc.py b/distutils/compilers/C/msvc.py index f67374ba..3606650f 100644 --- a/distutils/compilers/C/msvc.py +++ b/distutils/compilers/C/msvc.py @@ -17,15 +17,11 @@ import os import subprocess import tempfile -from collections.abc import Iterable, Iterator +from collections.abc import Iterable, Iterator, Sequence +from itertools import count from pathlib import Path from typing import ClassVar -with contextlib.suppress(ImportError): - import winreg - -from itertools import count - from ..errors import PlatformError from ..logging import get_logger from ..platform.detect import get_host_platform, get_platform @@ -33,6 +29,9 @@ from .base import gen_lib_options from .errors import CompileError, LibError, LinkError +with contextlib.suppress(ImportError): + import winreg + log = get_logger(__name__) @@ -618,7 +617,13 @@ def link( else: log.debug("skipping %s (up-to-date)", output_filename) - def call(self, cmd, *, env=None, **kwargs): + def call( + self, + cmd: Sequence[bytes | os.PathLike[bytes] | str | os.PathLike[str]], + *, + env=None, + **kwargs, + ) -> None: env = dict(os.environ, PATH=self._paths) return super().call(cmd, env=env, **kwargs) diff --git a/distutils/spawn.py b/distutils/spawn.py index d4db4791..f511a4c9 100644 --- a/distutils/spawn.py +++ b/distutils/spawn.py @@ -11,11 +11,15 @@ import subprocess import sys import warnings -from collections.abc import MutableSequence +from collections.abc import Sequence +from typing import TYPE_CHECKING from ._log import log from .errors import DistutilsExecError +if TYPE_CHECKING: + from subprocess import _ENV + @contextlib.contextmanager def _translate_errors(cmd): @@ -30,7 +34,12 @@ def _translate_errors(cmd): ) from err -def spawn(cmd: MutableSequence[bytes | str | os.PathLike[str]], **kwargs) -> None: +def spawn( + cmd: Sequence[bytes | os.PathLike[bytes] | str | os.PathLike[str]], + *, + env: _ENV | None = None, + **kwargs, +) -> None: """Run another program, specified as a command list 'cmd', in a new process. 'cmd' is just the argument list for the new process, ie. @@ -42,7 +51,7 @@ def spawn(cmd: MutableSequence[bytes | str | os.PathLike[str]], **kwargs) -> Non """ log.info(subprocess.list2cmdline(cmd)) with _translate_errors(cmd): - subprocess.check_call(cmd, **kwargs) + subprocess.check_call(cmd, env=env, **kwargs) def find_executable(executable: str, path: str | None = None) -> str | None: