From 860cd4a2c2a725bf52e6ff76b32e781381e42434 Mon Sep 17 00:00:00 2001 From: Jelle Zijlstra Date: Mon, 23 May 2022 19:05:40 -0700 Subject: [PATCH 01/10] fileinput: Fix TypeVar usage Fixes #7922, part of #7928. Also discovered an apparent CPython bug in the process: python/cpython#93157 --- stdlib/fileinput.pyi | 229 ++++++++++++++++++++++++++++++++++++++----- 1 file changed, 207 insertions(+), 22 deletions(-) diff --git a/stdlib/fileinput.pyi b/stdlib/fileinput.pyi index 0ef8c14ddaac..00097de497d0 100644 --- a/stdlib/fileinput.pyi +++ b/stdlib/fileinput.pyi @@ -2,7 +2,8 @@ import sys from _typeshed import Self, StrOrBytesPath from collections.abc import Callable, Iterable, Iterator from types import TracebackType -from typing import IO, Any, AnyStr, Generic +from typing_extensions import Protocol +from typing import IO, Any, AnyStr, Generic, Literal, overload __all__ = [ "input", @@ -19,40 +20,129 @@ __all__ = [ "hook_encoded", ] +class _HasReadlineAndFileno(Protocol[AnyStr]): + def readline(self) -> AnyStr: ... + def fileno(self) -> int: ... + if sys.version_info >= (3, 9): from types import GenericAlias if sys.version_info >= (3, 10): + # encoding and errors are added + @overload + def input( + files: StrOrBytesPath | Iterable[StrOrBytesPath] | None = ..., + inplace: bool = ..., + backup: str = ..., + *, + mode: Literal["r"] = ..., + openhook: Callable[[StrOrBytesPath, str], _HasReadlineAndFileno[str]] = ..., + encoding: str | None = ..., + errors: str | None = ..., + ) -> FileInput[str]: ... + @overload def input( files: StrOrBytesPath | Iterable[StrOrBytesPath] | None = ..., inplace: bool = ..., backup: str = ..., *, - mode: str = ..., - openhook: Callable[[StrOrBytesPath, str], IO[AnyStr]] = ..., + mode: Literal["rb"], + openhook: Callable[[StrOrBytesPath, str], _HasReadlineAndFileno[bytes]] = ..., + encoding: None = ..., + errors: None = ..., + ) -> FileInput[bytes]: ... + @overload + def input( + files: StrOrBytesPath | Iterable[StrOrBytesPath] | None = ..., + inplace: bool = ..., + backup: str = ..., + *, + mode: str, + openhook: Callable[[StrOrBytesPath, str], _HasReadlineAndFileno[Any]] = ..., encoding: str | None = ..., errors: str | None = ..., - ) -> FileInput[AnyStr]: ... + ) -> FileInput[Any]: ... elif sys.version_info >= (3, 8): + # bufsize is dropped and mode and openhook become keyword-only + @overload + def input( + files: StrOrBytesPath | Iterable[StrOrBytesPath] | None = ..., + inplace: bool = ..., + backup: str = ..., + *, + mode: Literal["r"] = ..., + openhook: Callable[[StrOrBytesPath, str], _HasReadlineAndFileno[str]] = ..., + ) -> FileInput[str]: ... + @overload def input( files: StrOrBytesPath | Iterable[StrOrBytesPath] | None = ..., inplace: bool = ..., backup: str = ..., *, - mode: str = ..., - openhook: Callable[[StrOrBytesPath, str], IO[AnyStr]] = ..., - ) -> FileInput[AnyStr]: ... + mode: Literal["rb"], + openhook: Callable[[StrOrBytesPath, str], _HasReadlineAndFileno[bytes]] = ..., + ) -> FileInput[bytes]: ... + @overload + def input( + files: StrOrBytesPath | Iterable[StrOrBytesPath] | None = ..., + inplace: bool = ..., + backup: str = ..., + *, + mode: str, + openhook: Callable[[StrOrBytesPath, str], _HasReadlineAndFileno[Any]] = ..., + ) -> FileInput[Any]: ... else: + @overload + def input( + files: StrOrBytesPath | Iterable[StrOrBytesPath] | None = ..., + inplace: bool = ..., + backup: str = ..., + bufsize: int = ..., + mode: Literal["r"] = ..., + openhook: Callable[[StrOrBytesPath, str], _HasReadlineAndFileno[str]] = ..., + ) -> FileInput[str]: ... + # Because mode isn't keyword-only here yet, we need two overloads each for + # the bytes case and the fallback case. + @overload def input( files: StrOrBytesPath | Iterable[StrOrBytesPath] | None = ..., inplace: bool = ..., backup: str = ..., bufsize: int = ..., - mode: str = ..., - openhook: Callable[[StrOrBytesPath, str], IO[AnyStr]] = ..., - ) -> FileInput[AnyStr]: ... + *, + mode: Literal["rb"], + openhook: Callable[[StrOrBytesPath, str], _HasReadlineAndFileno[bytes]] = ..., + ) -> FileInput[bytes]: ... + @overload + def input( + files: StrOrBytesPath | Iterable[StrOrBytesPath] | None, + inplace: bool, + backup: str, + bufsize: int, + mode: Literal["rb"], + openhook: Callable[[StrOrBytesPath, str], _HasReadlineAndFileno[bytes]] = ..., + ) -> FileInput[bytes]: ... + @overload + def input( + files: StrOrBytesPath | Iterable[StrOrBytesPath] | None = ..., + inplace: bool = ..., + backup: str = ..., + bufsize: int = ..., + *, + mode: str, + openhook: Callable[[StrOrBytesPath, str], _HasReadlineAndFileno[Any]] = ..., + ) -> FileInput[Any]: ... + @overload + def input( + files: StrOrBytesPath | Iterable[StrOrBytesPath] | None, + inplace: bool, + backup: str, + bufsize: int, + mode: str, + openhook: Callable[[StrOrBytesPath, str], _HasReadlineAndFileno[Any]] = ..., + ) -> FileInput[Any]: ... def close() -> None: ... def nextfile() -> None: ... @@ -65,36 +155,131 @@ def isstdin() -> bool: ... class FileInput(Iterator[AnyStr], Generic[AnyStr]): if sys.version_info >= (3, 10): + # encoding and errors are added + @overload def __init__( - self, - files: None | StrOrBytesPath | Iterable[StrOrBytesPath] = ..., + self: FileInput[str], + files: StrOrBytesPath | Iterable[StrOrBytesPath] | None = ..., inplace: bool = ..., backup: str = ..., *, - mode: str = ..., - openhook: Callable[[StrOrBytesPath, str], IO[AnyStr]] = ..., + mode: Literal["r"] = ..., + openhook: Callable[[StrOrBytesPath, str], _HasReadlineAndFileno[str]] = ..., encoding: str | None = ..., errors: str | None = ..., ) -> None: ... + @overload + def __init__( + self: FileInput[bytes], + files: StrOrBytesPath | Iterable[StrOrBytesPath] | None = ..., + inplace: bool = ..., + backup: str = ..., + *, + mode: Literal["rb"], + openhook: Callable[[StrOrBytesPath, str], _HasReadlineAndFileno[bytes]] = ..., + encoding: None = ..., + errors: None = ..., + ) -> None: ... + @overload + def __init__( + self: FileInput[Any], + files: StrOrBytesPath | Iterable[StrOrBytesPath] | None = ..., + inplace: bool = ..., + backup: str = ..., + *, + mode: str, + openhook: Callable[[StrOrBytesPath, str], _HasReadlineAndFileno[Any]] = ..., + encoding: str | None = ..., + errors: str | None = ..., + ) -> None: ... + elif sys.version_info >= (3, 8): + # bufsize is dropped and mode and openhook become keyword-only + @overload + def __init__( + self: FileInput[str], + files: StrOrBytesPath | Iterable[StrOrBytesPath] | None = ..., + inplace: bool = ..., + backup: str = ..., + *, + mode: Literal["r"] = ..., + openhook: Callable[[StrOrBytesPath, str], _HasReadlineAndFileno[str]] = ..., + ) -> None: ... + @overload def __init__( - self, - files: None | StrOrBytesPath | Iterable[StrOrBytesPath] = ..., + self: FileInput[bytes], + files: StrOrBytesPath | Iterable[StrOrBytesPath] | None = ..., inplace: bool = ..., backup: str = ..., *, - mode: str = ..., - openhook: Callable[[StrOrBytesPath, str], IO[AnyStr]] = ..., + mode: Literal["rb"], + openhook: Callable[[StrOrBytesPath, str], _HasReadlineAndFileno[bytes]] = ..., ) -> None: ... + @overload + def __init__( + self: FileInput[Any], + files: StrOrBytesPath | Iterable[StrOrBytesPath] | None = ..., + inplace: bool = ..., + backup: str = ..., + *, + mode: str, + openhook: Callable[[StrOrBytesPath, str], _HasReadlineAndFileno[Any]] = ..., + ) -> None: ... + else: + @overload + def __init__( + self: FileInput[str], + files: StrOrBytesPath | Iterable[StrOrBytesPath] | None = ..., + inplace: bool = ..., + backup: str = ..., + bufsize: int = ..., + mode: Literal["r"] = ..., + openhook: Callable[[StrOrBytesPath, str], _HasReadlineAndFileno[str]] = ..., + ) -> None: ... + # Because mode isn't keyword-only here yet, we need two overloads each for + # the bytes case and the fallback case. + @overload def __init__( - self, - files: None | StrOrBytesPath | Iterable[StrOrBytesPath] = ..., + self: FileInput[bytes], + files: StrOrBytesPath | Iterable[StrOrBytesPath] | None = ..., inplace: bool = ..., backup: str = ..., bufsize: int = ..., - mode: str = ..., - openhook: Callable[[StrOrBytesPath, str], IO[AnyStr]] = ..., + *, + mode: Literal["rb"], + openhook: Callable[[StrOrBytesPath, str], _HasReadlineAndFileno[bytes]] = ..., + ) -> None: ... + @overload + def __init__( + self: FileInput[bytes], + files: StrOrBytesPath | Iterable[StrOrBytesPath] | None, + inplace: bool, + backup: str, + bufsize: int, + mode: Literal["rb"], + openhook: Callable[[StrOrBytesPath, str], _HasReadlineAndFileno[bytes]] = ..., + ) -> None: ... + @overload + def __init__( + self: FileInput[Any], + files: StrOrBytesPath | Iterable[StrOrBytesPath] | None = ..., + inplace: bool = ..., + backup: str = ..., + bufsize: int = ..., + *, + mode: str, + openhook: Callable[[StrOrBytesPath, str], _HasReadlineAndFileno[Any]] = ..., + ) -> None: ... + @overload + def __init__( + self: FileInput[Any], + files: StrOrBytesPath | Iterable[StrOrBytesPath] | None, + inplace: bool, + backup: str, + bufsize: int, + mode: str, + openhook: Callable[[StrOrBytesPath, str], _HasReadlineAndFileno[Any]] = ..., ) -> None: ... def __del__(self) -> None: ... From ed20193266a3395e14f8d2cf4e48b1deb262a072 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 24 May 2022 02:08:42 +0000 Subject: [PATCH 02/10] [pre-commit.ci] auto fixes from pre-commit.com hooks --- stdlib/fileinput.pyi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stdlib/fileinput.pyi b/stdlib/fileinput.pyi index 00097de497d0..0ea1dff50508 100644 --- a/stdlib/fileinput.pyi +++ b/stdlib/fileinput.pyi @@ -2,8 +2,8 @@ import sys from _typeshed import Self, StrOrBytesPath from collections.abc import Callable, Iterable, Iterator from types import TracebackType -from typing_extensions import Protocol from typing import IO, Any, AnyStr, Generic, Literal, overload +from typing_extensions import Protocol __all__ = [ "input", From c95e8c8aeea9ccf527e1d58ec1218d0bf408d8bd Mon Sep 17 00:00:00 2001 From: Jelle Zijlstra Date: Mon, 23 May 2022 19:19:51 -0700 Subject: [PATCH 03/10] fixes --- stdlib/fileinput.pyi | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/stdlib/fileinput.pyi b/stdlib/fileinput.pyi index 0ea1dff50508..72a34f37afa3 100644 --- a/stdlib/fileinput.pyi +++ b/stdlib/fileinput.pyi @@ -2,8 +2,8 @@ import sys from _typeshed import Self, StrOrBytesPath from collections.abc import Callable, Iterable, Iterator from types import TracebackType -from typing import IO, Any, AnyStr, Generic, Literal, overload -from typing_extensions import Protocol +from typing import IO, Any, AnyStr, Generic, overload, TypeVar +from typing_extensions import Literal, Protocol __all__ = [ "input", @@ -20,8 +20,10 @@ __all__ = [ "hook_encoded", ] -class _HasReadlineAndFileno(Protocol[AnyStr]): - def readline(self) -> AnyStr: ... +_AnyStr_co = TypeVar("_AnyStr_co", str, bytes) + +class _HasReadlineAndFileno(Protocol[_AnyStr_co]): + def readline(self) -> _AnyStr_co: ... def fileno(self) -> int: ... if sys.version_info >= (3, 9): From 378451219696bb2e77c5c9c4146bbedea20fbf6b Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 24 May 2022 02:21:05 +0000 Subject: [PATCH 04/10] [pre-commit.ci] auto fixes from pre-commit.com hooks --- stdlib/fileinput.pyi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stdlib/fileinput.pyi b/stdlib/fileinput.pyi index 72a34f37afa3..37fc30875ae7 100644 --- a/stdlib/fileinput.pyi +++ b/stdlib/fileinput.pyi @@ -2,7 +2,7 @@ import sys from _typeshed import Self, StrOrBytesPath from collections.abc import Callable, Iterable, Iterator from types import TracebackType -from typing import IO, Any, AnyStr, Generic, overload, TypeVar +from typing import IO, Any, AnyStr, Generic, TypeVar, overload from typing_extensions import Literal, Protocol __all__ = [ From 1bdf7cdec7e983e71a2d84967aad3302a9a86df6 Mon Sep 17 00:00:00 2001 From: Jelle Zijlstra Date: Mon, 23 May 2022 19:22:48 -0700 Subject: [PATCH 05/10] make it actually covariant --- stdlib/fileinput.pyi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stdlib/fileinput.pyi b/stdlib/fileinput.pyi index 37fc30875ae7..566696d8f842 100644 --- a/stdlib/fileinput.pyi +++ b/stdlib/fileinput.pyi @@ -20,7 +20,7 @@ __all__ = [ "hook_encoded", ] -_AnyStr_co = TypeVar("_AnyStr_co", str, bytes) +_AnyStr_co = TypeVar("_AnyStr_co", str, bytes, covariant=True) class _HasReadlineAndFileno(Protocol[_AnyStr_co]): def readline(self) -> _AnyStr_co: ... From baeed87eefe06d53c45b646af762ec96a5fdf800 Mon Sep 17 00:00:00 2001 From: Jelle Zijlstra Date: Mon, 23 May 2022 19:28:50 -0700 Subject: [PATCH 06/10] openhook may be None --- stdlib/fileinput.pyi | 44 ++++++++++++++++++++++---------------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/stdlib/fileinput.pyi b/stdlib/fileinput.pyi index 566696d8f842..d12d4eb29204 100644 --- a/stdlib/fileinput.pyi +++ b/stdlib/fileinput.pyi @@ -38,7 +38,7 @@ if sys.version_info >= (3, 10): backup: str = ..., *, mode: Literal["r"] = ..., - openhook: Callable[[StrOrBytesPath, str], _HasReadlineAndFileno[str]] = ..., + openhook: Callable[[StrOrBytesPath, str], _HasReadlineAndFileno[str]] | None = ..., encoding: str | None = ..., errors: str | None = ..., ) -> FileInput[str]: ... @@ -49,7 +49,7 @@ if sys.version_info >= (3, 10): backup: str = ..., *, mode: Literal["rb"], - openhook: Callable[[StrOrBytesPath, str], _HasReadlineAndFileno[bytes]] = ..., + openhook: Callable[[StrOrBytesPath, str], _HasReadlineAndFileno[bytes]] | None = ..., encoding: None = ..., errors: None = ..., ) -> FileInput[bytes]: ... @@ -60,7 +60,7 @@ if sys.version_info >= (3, 10): backup: str = ..., *, mode: str, - openhook: Callable[[StrOrBytesPath, str], _HasReadlineAndFileno[Any]] = ..., + openhook: Callable[[StrOrBytesPath, str], _HasReadlineAndFileno[Any]] | None = ..., encoding: str | None = ..., errors: str | None = ..., ) -> FileInput[Any]: ... @@ -74,7 +74,7 @@ elif sys.version_info >= (3, 8): backup: str = ..., *, mode: Literal["r"] = ..., - openhook: Callable[[StrOrBytesPath, str], _HasReadlineAndFileno[str]] = ..., + openhook: Callable[[StrOrBytesPath, str], _HasReadlineAndFileno[str]] | None = ..., ) -> FileInput[str]: ... @overload def input( @@ -83,7 +83,7 @@ elif sys.version_info >= (3, 8): backup: str = ..., *, mode: Literal["rb"], - openhook: Callable[[StrOrBytesPath, str], _HasReadlineAndFileno[bytes]] = ..., + openhook: Callable[[StrOrBytesPath, str], _HasReadlineAndFileno[bytes]] | None = ..., ) -> FileInput[bytes]: ... @overload def input( @@ -92,7 +92,7 @@ elif sys.version_info >= (3, 8): backup: str = ..., *, mode: str, - openhook: Callable[[StrOrBytesPath, str], _HasReadlineAndFileno[Any]] = ..., + openhook: Callable[[StrOrBytesPath, str], _HasReadlineAndFileno[Any]] | None = ..., ) -> FileInput[Any]: ... else: @@ -103,7 +103,7 @@ else: backup: str = ..., bufsize: int = ..., mode: Literal["r"] = ..., - openhook: Callable[[StrOrBytesPath, str], _HasReadlineAndFileno[str]] = ..., + openhook: Callable[[StrOrBytesPath, str], _HasReadlineAndFileno[str]] | None = ..., ) -> FileInput[str]: ... # Because mode isn't keyword-only here yet, we need two overloads each for # the bytes case and the fallback case. @@ -115,7 +115,7 @@ else: bufsize: int = ..., *, mode: Literal["rb"], - openhook: Callable[[StrOrBytesPath, str], _HasReadlineAndFileno[bytes]] = ..., + openhook: Callable[[StrOrBytesPath, str], _HasReadlineAndFileno[bytes]] | None = ..., ) -> FileInput[bytes]: ... @overload def input( @@ -124,7 +124,7 @@ else: backup: str, bufsize: int, mode: Literal["rb"], - openhook: Callable[[StrOrBytesPath, str], _HasReadlineAndFileno[bytes]] = ..., + openhook: Callable[[StrOrBytesPath, str], _HasReadlineAndFileno[bytes]] | None = ..., ) -> FileInput[bytes]: ... @overload def input( @@ -134,7 +134,7 @@ else: bufsize: int = ..., *, mode: str, - openhook: Callable[[StrOrBytesPath, str], _HasReadlineAndFileno[Any]] = ..., + openhook: Callable[[StrOrBytesPath, str], _HasReadlineAndFileno[Any]] | None = ..., ) -> FileInput[Any]: ... @overload def input( @@ -143,7 +143,7 @@ else: backup: str, bufsize: int, mode: str, - openhook: Callable[[StrOrBytesPath, str], _HasReadlineAndFileno[Any]] = ..., + openhook: Callable[[StrOrBytesPath, str], _HasReadlineAndFileno[Any]] | None = ..., ) -> FileInput[Any]: ... def close() -> None: ... @@ -166,7 +166,7 @@ class FileInput(Iterator[AnyStr], Generic[AnyStr]): backup: str = ..., *, mode: Literal["r"] = ..., - openhook: Callable[[StrOrBytesPath, str], _HasReadlineAndFileno[str]] = ..., + openhook: Callable[[StrOrBytesPath, str], _HasReadlineAndFileno[str]] | None = ..., encoding: str | None = ..., errors: str | None = ..., ) -> None: ... @@ -178,7 +178,7 @@ class FileInput(Iterator[AnyStr], Generic[AnyStr]): backup: str = ..., *, mode: Literal["rb"], - openhook: Callable[[StrOrBytesPath, str], _HasReadlineAndFileno[bytes]] = ..., + openhook: Callable[[StrOrBytesPath, str], _HasReadlineAndFileno[bytes]] | None = ..., encoding: None = ..., errors: None = ..., ) -> None: ... @@ -190,7 +190,7 @@ class FileInput(Iterator[AnyStr], Generic[AnyStr]): backup: str = ..., *, mode: str, - openhook: Callable[[StrOrBytesPath, str], _HasReadlineAndFileno[Any]] = ..., + openhook: Callable[[StrOrBytesPath, str], _HasReadlineAndFileno[Any]] | None = ..., encoding: str | None = ..., errors: str | None = ..., ) -> None: ... @@ -205,7 +205,7 @@ class FileInput(Iterator[AnyStr], Generic[AnyStr]): backup: str = ..., *, mode: Literal["r"] = ..., - openhook: Callable[[StrOrBytesPath, str], _HasReadlineAndFileno[str]] = ..., + openhook: Callable[[StrOrBytesPath, str], _HasReadlineAndFileno[str]] | None = ..., ) -> None: ... @overload def __init__( @@ -215,7 +215,7 @@ class FileInput(Iterator[AnyStr], Generic[AnyStr]): backup: str = ..., *, mode: Literal["rb"], - openhook: Callable[[StrOrBytesPath, str], _HasReadlineAndFileno[bytes]] = ..., + openhook: Callable[[StrOrBytesPath, str], _HasReadlineAndFileno[bytes]] | None = ..., ) -> None: ... @overload def __init__( @@ -225,7 +225,7 @@ class FileInput(Iterator[AnyStr], Generic[AnyStr]): backup: str = ..., *, mode: str, - openhook: Callable[[StrOrBytesPath, str], _HasReadlineAndFileno[Any]] = ..., + openhook: Callable[[StrOrBytesPath, str], _HasReadlineAndFileno[Any]] | None = ..., ) -> None: ... else: @@ -237,7 +237,7 @@ class FileInput(Iterator[AnyStr], Generic[AnyStr]): backup: str = ..., bufsize: int = ..., mode: Literal["r"] = ..., - openhook: Callable[[StrOrBytesPath, str], _HasReadlineAndFileno[str]] = ..., + openhook: Callable[[StrOrBytesPath, str], _HasReadlineAndFileno[str]] | None = ..., ) -> None: ... # Because mode isn't keyword-only here yet, we need two overloads each for # the bytes case and the fallback case. @@ -250,7 +250,7 @@ class FileInput(Iterator[AnyStr], Generic[AnyStr]): bufsize: int = ..., *, mode: Literal["rb"], - openhook: Callable[[StrOrBytesPath, str], _HasReadlineAndFileno[bytes]] = ..., + openhook: Callable[[StrOrBytesPath, str], _HasReadlineAndFileno[bytes]] | None = ..., ) -> None: ... @overload def __init__( @@ -260,7 +260,7 @@ class FileInput(Iterator[AnyStr], Generic[AnyStr]): backup: str, bufsize: int, mode: Literal["rb"], - openhook: Callable[[StrOrBytesPath, str], _HasReadlineAndFileno[bytes]] = ..., + openhook: Callable[[StrOrBytesPath, str], _HasReadlineAndFileno[bytes]] | None = ..., ) -> None: ... @overload def __init__( @@ -271,7 +271,7 @@ class FileInput(Iterator[AnyStr], Generic[AnyStr]): bufsize: int = ..., *, mode: str, - openhook: Callable[[StrOrBytesPath, str], _HasReadlineAndFileno[Any]] = ..., + openhook: Callable[[StrOrBytesPath, str], _HasReadlineAndFileno[Any]] | None = ..., ) -> None: ... @overload def __init__( @@ -281,7 +281,7 @@ class FileInput(Iterator[AnyStr], Generic[AnyStr]): backup: str, bufsize: int, mode: str, - openhook: Callable[[StrOrBytesPath, str], _HasReadlineAndFileno[Any]] = ..., + openhook: Callable[[StrOrBytesPath, str], _HasReadlineAndFileno[Any]] | None = ..., ) -> None: ... def __del__(self) -> None: ... From ec3cb3f7196699bf5653fcba5ee60fecb85fd273 Mon Sep 17 00:00:00 2001 From: Jelle Zijlstra Date: Mon, 23 May 2022 19:31:40 -0700 Subject: [PATCH 07/10] typing.Protocol --- stdlib/fileinput.pyi | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/stdlib/fileinput.pyi b/stdlib/fileinput.pyi index d12d4eb29204..bf0143f39317 100644 --- a/stdlib/fileinput.pyi +++ b/stdlib/fileinput.pyi @@ -2,8 +2,8 @@ import sys from _typeshed import Self, StrOrBytesPath from collections.abc import Callable, Iterable, Iterator from types import TracebackType -from typing import IO, Any, AnyStr, Generic, TypeVar, overload -from typing_extensions import Literal, Protocol +from typing import IO, Any, AnyStr, Generic, Protocol, TypeVar, overload +from typing_extensions import Literal __all__ = [ "input", From f27e4a2c1392ed815bc29f4b46e8e6d9e436a677 Mon Sep 17 00:00:00 2001 From: Jelle Zijlstra Date: Tue, 24 May 2022 09:20:35 -0700 Subject: [PATCH 08/10] U modes --- stdlib/fileinput.pyi | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/stdlib/fileinput.pyi b/stdlib/fileinput.pyi index bf0143f39317..0f876d3f1a79 100644 --- a/stdlib/fileinput.pyi +++ b/stdlib/fileinput.pyi @@ -5,6 +5,9 @@ from types import TracebackType from typing import IO, Any, AnyStr, Generic, Protocol, TypeVar, overload from typing_extensions import Literal +if sys.version_info >= (3, 9): + from types import GenericAlias + __all__ = [ "input", "close", @@ -20,15 +23,17 @@ __all__ = [ "hook_encoded", ] +if sys.version_info <= (3, 11): + _TextMode = Literal["r"] +else: + _TextMode = Literal["r", "rU", "U"] + _AnyStr_co = TypeVar("_AnyStr_co", str, bytes, covariant=True) class _HasReadlineAndFileno(Protocol[_AnyStr_co]): def readline(self) -> _AnyStr_co: ... def fileno(self) -> int: ... -if sys.version_info >= (3, 9): - from types import GenericAlias - if sys.version_info >= (3, 10): # encoding and errors are added @overload @@ -37,7 +42,7 @@ if sys.version_info >= (3, 10): inplace: bool = ..., backup: str = ..., *, - mode: Literal["r"] = ..., + mode: _TextMode = ..., openhook: Callable[[StrOrBytesPath, str], _HasReadlineAndFileno[str]] | None = ..., encoding: str | None = ..., errors: str | None = ..., @@ -73,7 +78,7 @@ elif sys.version_info >= (3, 8): inplace: bool = ..., backup: str = ..., *, - mode: Literal["r"] = ..., + mode: _TextMode = ..., openhook: Callable[[StrOrBytesPath, str], _HasReadlineAndFileno[str]] | None = ..., ) -> FileInput[str]: ... @overload @@ -102,7 +107,7 @@ else: inplace: bool = ..., backup: str = ..., bufsize: int = ..., - mode: Literal["r"] = ..., + mode: _TextMode = ..., openhook: Callable[[StrOrBytesPath, str], _HasReadlineAndFileno[str]] | None = ..., ) -> FileInput[str]: ... # Because mode isn't keyword-only here yet, we need two overloads each for @@ -165,7 +170,7 @@ class FileInput(Iterator[AnyStr], Generic[AnyStr]): inplace: bool = ..., backup: str = ..., *, - mode: Literal["r"] = ..., + mode: _TextMode = ..., openhook: Callable[[StrOrBytesPath, str], _HasReadlineAndFileno[str]] | None = ..., encoding: str | None = ..., errors: str | None = ..., @@ -204,7 +209,7 @@ class FileInput(Iterator[AnyStr], Generic[AnyStr]): inplace: bool = ..., backup: str = ..., *, - mode: Literal["r"] = ..., + mode: _TextMode = ..., openhook: Callable[[StrOrBytesPath, str], _HasReadlineAndFileno[str]] | None = ..., ) -> None: ... @overload @@ -236,7 +241,7 @@ class FileInput(Iterator[AnyStr], Generic[AnyStr]): inplace: bool = ..., backup: str = ..., bufsize: int = ..., - mode: Literal["r"] = ..., + mode: _TextMode = ..., openhook: Callable[[StrOrBytesPath, str], _HasReadlineAndFileno[str]] | None = ..., ) -> None: ... # Because mode isn't keyword-only here yet, we need two overloads each for From 972f2f4808899191bfb7009f597af7a764c14a22 Mon Sep 17 00:00:00 2001 From: Jelle Zijlstra Date: Tue, 24 May 2022 09:21:09 -0700 Subject: [PATCH 09/10] other way around --- stdlib/fileinput.pyi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stdlib/fileinput.pyi b/stdlib/fileinput.pyi index 0f876d3f1a79..d91dba8e5e31 100644 --- a/stdlib/fileinput.pyi +++ b/stdlib/fileinput.pyi @@ -23,7 +23,7 @@ __all__ = [ "hook_encoded", ] -if sys.version_info <= (3, 11): +if sys.version_info >= (3, 11): _TextMode = Literal["r"] else: _TextMode = Literal["r", "rU", "U"] From 3852e80388b209df33bc2345f6a8ea704190962d Mon Sep 17 00:00:00 2001 From: Alex Waygood Date: Tue, 24 May 2022 17:26:49 +0100 Subject: [PATCH 10/10] Fix lint --- stdlib/fileinput.pyi | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/stdlib/fileinput.pyi b/stdlib/fileinput.pyi index d91dba8e5e31..0df88e553f49 100644 --- a/stdlib/fileinput.pyi +++ b/stdlib/fileinput.pyi @@ -3,7 +3,7 @@ from _typeshed import Self, StrOrBytesPath from collections.abc import Callable, Iterable, Iterator from types import TracebackType from typing import IO, Any, AnyStr, Generic, Protocol, TypeVar, overload -from typing_extensions import Literal +from typing_extensions import Literal, TypeAlias if sys.version_info >= (3, 9): from types import GenericAlias @@ -24,9 +24,9 @@ __all__ = [ ] if sys.version_info >= (3, 11): - _TextMode = Literal["r"] + _TextMode: TypeAlias = Literal["r"] else: - _TextMode = Literal["r", "rU", "U"] + _TextMode: TypeAlias = Literal["r", "rU", "U"] _AnyStr_co = TypeVar("_AnyStr_co", str, bytes, covariant=True)