From 58a4c08ab00107b223304fd1e236a56697963c38 Mon Sep 17 00:00:00 2001 From: Avasam Date: Wed, 5 Mar 2025 02:54:48 -0500 Subject: [PATCH] `shutil.which` cannot return `PathLike`, and fails with `cmd: PathLike` on Windows Python < 3.12 (#13580) --- stdlib/shutil.pyi | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/stdlib/shutil.pyi b/stdlib/shutil.pyi index 4a19a96a3..0fe560fd9 100644 --- a/stdlib/shutil.pyi +++ b/stdlib/shutil.pyi @@ -3,7 +3,7 @@ import sys from _typeshed import BytesPath, ExcInfo, FileDescriptorOrPath, StrOrBytesPath, StrPath, SupportsRead, SupportsWrite from collections.abc import Callable, Iterable, Sequence from tarfile import _TarfileFilter -from typing import Any, AnyStr, NamedTuple, Protocol, TypeVar, overload +from typing import Any, AnyStr, NamedTuple, NoReturn, Protocol, TypeVar, overload from typing_extensions import TypeAlias, deprecated __all__ = [ @@ -36,7 +36,6 @@ __all__ = [ ] _StrOrBytesPathT = TypeVar("_StrOrBytesPathT", bound=StrOrBytesPath) -_StrPathT = TypeVar("_StrPathT", bound=StrPath) # Return value of some functions that may either return a path-like object that was passed in or # a string _PathReturn: TypeAlias = Any @@ -185,8 +184,13 @@ else: @overload def chown(path: FileDescriptorOrPath, user: str | int, group: str | int) -> None: ... +if sys.platform == "win32" and sys.version_info < (3, 12): + @overload + @deprecated("On Windows before Python 3.12, using a PathLike as `cmd` would always fail or return `None`.") + def which(cmd: os.PathLike[str], mode: int = 1, path: StrPath | None = None) -> NoReturn: ... + @overload -def which(cmd: _StrPathT, mode: int = 1, path: StrPath | None = None) -> str | _StrPathT | None: ... +def which(cmd: StrPath, mode: int = 1, path: StrPath | None = None) -> str | None: ... @overload def which(cmd: bytes, mode: int = 1, path: StrPath | None = None) -> bytes | None: ... def make_archive(