From 49cd02456cf94fe578c504cc960ace07e459366e Mon Sep 17 00:00:00 2001 From: Akuli Date: Sun, 9 May 2021 01:30:26 +0300 Subject: [PATCH] fixes for os.path.commonpath and os.path.commonprefix (#5363) --- stdlib/genericpath.pyi | 9 ++------- stdlib/ntpath.pyi | 12 ++---------- stdlib/os/path.pyi | 30 +++++++++++++++++++----------- stdlib/posixpath.pyi | 12 ++---------- 4 files changed, 25 insertions(+), 38 deletions(-) diff --git a/stdlib/genericpath.pyi b/stdlib/genericpath.pyi index fc314f0a1..74dc81932 100644 --- a/stdlib/genericpath.pyi +++ b/stdlib/genericpath.pyi @@ -1,12 +1,7 @@ import sys from _typeshed import AnyPath -from typing import AnyStr, Sequence, Text - -if sys.version_info >= (3, 0): - def commonprefix(m: Sequence[str]) -> str: ... - -else: - def commonprefix(m: Sequence[AnyStr]) -> AnyStr: ... +from os.path import commonprefix as commonprefix +from typing import Text def exists(path: AnyPath) -> bool: ... def isfile(path: Text) -> bool: ... diff --git a/stdlib/ntpath.pyi b/stdlib/ntpath.pyi index bcd58b532..6af6cbbc2 100644 --- a/stdlib/ntpath.pyi +++ b/stdlib/ntpath.pyi @@ -3,7 +3,8 @@ import sys from _typeshed import AnyPath, BytesPath, StrPath from genericpath import exists as exists from os import PathLike -from typing import Any, AnyStr, Optional, Sequence, Tuple, TypeVar, overload +from os.path import commonpath as commonpath, commonprefix as commonprefix, lexists as lexists +from typing import AnyStr, Optional, Tuple, TypeVar, overload _T = TypeVar("_T") @@ -57,15 +58,6 @@ def realpath(path: PathLike[AnyStr]) -> AnyStr: ... @overload def realpath(path: AnyStr) -> AnyStr: ... -# In reality it returns str for sequences of StrPath and bytes for sequences -# of BytesPath, but mypy does not accept such a signature. -def commonpath(paths: Sequence[AnyPath]) -> Any: ... - -# NOTE: Empty lists results in '' (str) regardless of contained type. -# So, fall back to Any -def commonprefix(m: Sequence[AnyPath]) -> Any: ... -def lexists(path: AnyPath) -> bool: ... - # These return float if os.stat_float_times() == True, # but int is a subclass of float. def getatime(filename: AnyPath) -> float: ... diff --git a/stdlib/os/path.pyi b/stdlib/os/path.pyi index a8b30eb71..66d5d6fea 100644 --- a/stdlib/os/path.pyi +++ b/stdlib/os/path.pyi @@ -1,11 +1,10 @@ import os import sys -from _typeshed import AnyPath, BytesPath, StrPath +from _typeshed import AnyPath, BytesPath, StrPath, SupportsLessThanT from genericpath import exists as exists from os import PathLike -from typing import Any, AnyStr, Optional, Sequence, Tuple, TypeVar, overload - -_T = TypeVar("_T") +from typing import AnyStr, List, Optional, Sequence, Tuple, Union, overload +from typing_extensions import Literal # ----- os.path variables ----- supports_unicode_filenames: bool @@ -77,14 +76,22 @@ else: @overload def realpath(filename: AnyStr) -> AnyStr: ... -# In reality it returns str for sequences of StrPath and bytes for sequences -# of BytesPath, but mypy does not accept such a signature. -def commonpath(paths: Sequence[AnyPath]) -> Any: ... +@overload +def commonpath(paths: Sequence[StrPath]) -> str: ... +@overload +def commonpath(paths: Sequence[BytesPath]) -> bytes: ... -# NOTE: Empty lists results in '' (str) regardless of contained type. -# So, fall back to Any -def commonprefix(m: Sequence[AnyPath]) -> Any: ... -def lexists(path: AnyPath) -> bool: ... +# All overloads can return empty string. Ideally, Literal[""] would be a valid +# Iterable[T], so that Union[List[T], Literal[""]] could be used as a return +# type. But because this only works when T is str, we need Sequence[T] instead. +@overload +def commonprefix(m: Sequence[StrPath]) -> str: ... +@overload +def commonprefix(m: Sequence[BytesPath]) -> Union[bytes, Literal[""]]: ... +@overload +def commonprefix(m: Sequence[List[SupportsLessThanT]]) -> Sequence[SupportsLessThanT]: ... +@overload +def commonprefix(m: Sequence[Tuple[SupportsLessThanT, ...]]) -> Sequence[SupportsLessThanT]: ... # These return float if os.stat_float_times() == True, # but int is a subclass of float. @@ -92,6 +99,7 @@ def getatime(filename: AnyPath) -> float: ... def getmtime(filename: AnyPath) -> float: ... def getctime(filename: AnyPath) -> float: ... def getsize(filename: AnyPath) -> int: ... +def lexists(path: AnyPath) -> bool: ... def isabs(s: AnyPath) -> bool: ... def isfile(path: AnyPath) -> bool: ... def isdir(s: AnyPath) -> bool: ... diff --git a/stdlib/posixpath.pyi b/stdlib/posixpath.pyi index 2fcbe12f8..b9e26c6ac 100644 --- a/stdlib/posixpath.pyi +++ b/stdlib/posixpath.pyi @@ -3,7 +3,8 @@ import sys from _typeshed import AnyPath, BytesPath, StrPath from genericpath import exists as exists from os import PathLike -from typing import Any, AnyStr, Optional, Sequence, Tuple, TypeVar, overload +from os.path import commonpath as commonpath, commonprefix as commonprefix, lexists as lexists +from typing import AnyStr, Optional, Tuple, TypeVar, overload _T = TypeVar("_T") @@ -65,15 +66,6 @@ else: @overload def realpath(filename: AnyStr) -> AnyStr: ... -# In reality it returns str for sequences of StrPath and bytes for sequences -# of BytesPath, but mypy does not accept such a signature. -def commonpath(paths: Sequence[AnyPath]) -> Any: ... - -# NOTE: Empty lists results in '' (str) regardless of contained type. -# So, fall back to Any -def commonprefix(m: Sequence[AnyPath]) -> Any: ... -def lexists(path: AnyPath) -> bool: ... - # These return float if os.stat_float_times() == True, # but int is a subclass of float. def getatime(filename: AnyPath) -> float: ...