From 677c42d58f4a1929c4eb806dd7a59415509b7a74 Mon Sep 17 00:00:00 2001 From: Jelle Zijlstra Date: Sun, 28 May 2023 16:19:18 -0700 Subject: [PATCH 1/8] Use a Protocol as the argument for io.TextIOWrapper I ran into a false positive where gzip.GzipFile couldn't be assigned to io.TextIOWrapper. --- stdlib/io.pyi | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/stdlib/io.pyi b/stdlib/io.pyi index c114f839594f..4c8fd1475410 100644 --- a/stdlib/io.pyi +++ b/stdlib/io.pyi @@ -6,7 +6,7 @@ from _typeshed import FileDescriptorOrPath, ReadableBuffer, WriteableBuffer from collections.abc import Callable, Iterable, Iterator from os import _Opener from types import TracebackType -from typing import IO, Any, BinaryIO, TextIO +from typing import IO, Any, BinaryIO, Protocol, TextIO from typing_extensions import Literal, Self __all__ = [ @@ -144,10 +144,28 @@ class TextIOBase(IOBase): def readlines(self, __hint: int = -1) -> list[str]: ... # type: ignore[override] def read(self, __size: int | None = ...) -> str: ... +class _TextIOWrapperBuffer(Protocol): + def readable(self) -> bool: ... + def seekable(self) -> bool: ... + def writable(self) -> bool: ... + def isatty(self) -> bool: ... + def write(self, __s: bytes) -> object: ... + def flush(self) -> object: ... + def read(self, __n: int) -> ReadableBuffer: ... + def seek(self, __offset: int, __whence: int = ...) -> int: ... + def tell(self) -> int: ... + def truncate(self, __size: int | None = ...) -> int: ... + def fileno(self) -> int: ... + def close(self) -> None: ... + @property + def name(self) -> str: ... + @property + def closed(self) -> bool: ... + class TextIOWrapper(TextIOBase, TextIO): # type: ignore[misc] # incompatible definitions of write in the base classes def __init__( self, - buffer: IO[bytes], + buffer: _TextIOWrapperBuffer, encoding: str | None = ..., errors: str | None = ..., newline: str | None = ..., @@ -155,7 +173,7 @@ class TextIOWrapper(TextIOBase, TextIO): # type: ignore[misc] # incompatible d write_through: bool = ..., ) -> None: ... @property - def buffer(self) -> BinaryIO: ... + def buffer(self) -> _TextIOWrapperBuffer: ... @property def closed(self) -> bool: ... @property From 7643545fea599442c0f065dd8484411c24fce686 Mon Sep 17 00:00:00 2001 From: Jelle Zijlstra Date: Sun, 28 May 2023 16:21:42 -0700 Subject: [PATCH 2/8] Ignore incompatible type --- stdlib/io.pyi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stdlib/io.pyi b/stdlib/io.pyi index 4c8fd1475410..bd4b86a55f92 100644 --- a/stdlib/io.pyi +++ b/stdlib/io.pyi @@ -173,7 +173,7 @@ class TextIOWrapper(TextIOBase, TextIO): # type: ignore[misc] # incompatible d write_through: bool = ..., ) -> None: ... @property - def buffer(self) -> _TextIOWrapperBuffer: ... + def buffer(self) -> _TextIOWrapperBuffer: ... # type: ignore[override] @property def closed(self) -> bool: ... @property From 4aefbeaec0b69666f873c4d7f5a609e40fa2f2dc Mon Sep 17 00:00:00 2001 From: Jelle Zijlstra Date: Tue, 30 May 2023 07:03:16 -0700 Subject: [PATCH 3/8] Try Sebastian's idea --- stdlib/io.pyi | 22 ++-------------------- 1 file changed, 2 insertions(+), 20 deletions(-) diff --git a/stdlib/io.pyi b/stdlib/io.pyi index bd4b86a55f92..aa25f644bfa2 100644 --- a/stdlib/io.pyi +++ b/stdlib/io.pyi @@ -144,28 +144,10 @@ class TextIOBase(IOBase): def readlines(self, __hint: int = -1) -> list[str]: ... # type: ignore[override] def read(self, __size: int | None = ...) -> str: ... -class _TextIOWrapperBuffer(Protocol): - def readable(self) -> bool: ... - def seekable(self) -> bool: ... - def writable(self) -> bool: ... - def isatty(self) -> bool: ... - def write(self, __s: bytes) -> object: ... - def flush(self) -> object: ... - def read(self, __n: int) -> ReadableBuffer: ... - def seek(self, __offset: int, __whence: int = ...) -> int: ... - def tell(self) -> int: ... - def truncate(self, __size: int | None = ...) -> int: ... - def fileno(self) -> int: ... - def close(self) -> None: ... - @property - def name(self) -> str: ... - @property - def closed(self) -> bool: ... - class TextIOWrapper(TextIOBase, TextIO): # type: ignore[misc] # incompatible definitions of write in the base classes def __init__( self, - buffer: _TextIOWrapperBuffer, + buffer: BufferedIOBase, encoding: str | None = ..., errors: str | None = ..., newline: str | None = ..., @@ -173,7 +155,7 @@ class TextIOWrapper(TextIOBase, TextIO): # type: ignore[misc] # incompatible d write_through: bool = ..., ) -> None: ... @property - def buffer(self) -> _TextIOWrapperBuffer: ... # type: ignore[override] + def buffer(self) -> BufferedIOBase: ... @property def closed(self) -> bool: ... @property From dcad196149ceb4f529b0dd57ddf2e1b6e4eb6724 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 30 May 2023 14:04:30 +0000 Subject: [PATCH 4/8] [pre-commit.ci] auto fixes from pre-commit.com hooks --- stdlib/io.pyi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stdlib/io.pyi b/stdlib/io.pyi index aa25f644bfa2..635d9e226e8f 100644 --- a/stdlib/io.pyi +++ b/stdlib/io.pyi @@ -6,7 +6,7 @@ from _typeshed import FileDescriptorOrPath, ReadableBuffer, WriteableBuffer from collections.abc import Callable, Iterable, Iterator from os import _Opener from types import TracebackType -from typing import IO, Any, BinaryIO, Protocol, TextIO +from typing import IO, Any, BinaryIO, TextIO from typing_extensions import Literal, Self __all__ = [ From 5131054697d3e3edccbf7f6b09d443525bcb3510 Mon Sep 17 00:00:00 2001 From: Sebastian Rittau Date: Tue, 6 Jun 2023 13:36:42 +0200 Subject: [PATCH 5/8] Fix a mypy warning, add detach() Incorporates changes from #10266, so we don't have two PRs open. --- stdlib/io.pyi | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/stdlib/io.pyi b/stdlib/io.pyi index 635d9e226e8f..c0ac303cd6e8 100644 --- a/stdlib/io.pyi +++ b/stdlib/io.pyi @@ -155,7 +155,7 @@ class TextIOWrapper(TextIOBase, TextIO): # type: ignore[misc] # incompatible d write_through: bool = ..., ) -> None: ... @property - def buffer(self) -> BufferedIOBase: ... + def buffer(self) -> BufferedIOBase: ... # type: ignore[override] @property def closed(self) -> bool: ... @property @@ -178,6 +178,7 @@ class TextIOWrapper(TextIOBase, TextIO): # type: ignore[misc] # incompatible d def writelines(self, __lines: Iterable[str]) -> None: ... # type: ignore[override] def readline(self, __size: int = -1) -> str: ... # type: ignore[override] def readlines(self, __hint: int = -1) -> list[str]: ... # type: ignore[override] + def detach(self) -> BufferedIOBase: ... # type: ignore[override] def seek(self, __cookie: int, __whence: int = 0) -> int: ... # stubtest needs this class StringIO(TextIOWrapper): From 51f089b77a2fd03a66ba896a58497abb4ffdeb7f Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 6 Jun 2023 11:38:34 +0000 Subject: [PATCH 6/8] [pre-commit.ci] auto fixes from pre-commit.com hooks --- stdlib/io.pyi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stdlib/io.pyi b/stdlib/io.pyi index c0ac303cd6e8..0bccd5cd579d 100644 --- a/stdlib/io.pyi +++ b/stdlib/io.pyi @@ -178,7 +178,7 @@ class TextIOWrapper(TextIOBase, TextIO): # type: ignore[misc] # incompatible d def writelines(self, __lines: Iterable[str]) -> None: ... # type: ignore[override] def readline(self, __size: int = -1) -> str: ... # type: ignore[override] def readlines(self, __hint: int = -1) -> list[str]: ... # type: ignore[override] - def detach(self) -> BufferedIOBase: ... # type: ignore[override] + def detach(self) -> BufferedIOBase: ... # type: ignore[override] def seek(self, __cookie: int, __whence: int = 0) -> int: ... # stubtest needs this class StringIO(TextIOWrapper): From 355595e7c44c62ff72d8c21d6f23e86d303118a2 Mon Sep 17 00:00:00 2001 From: Jelle Zijlstra Date: Thu, 15 Jun 2023 18:19:15 -0700 Subject: [PATCH 7/8] Back to a Protocol --- stdlib/io.pyi | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/stdlib/io.pyi b/stdlib/io.pyi index 0bccd5cd579d..14c0ec3ae580 100644 --- a/stdlib/io.pyi +++ b/stdlib/io.pyi @@ -6,7 +6,7 @@ from _typeshed import FileDescriptorOrPath, ReadableBuffer, WriteableBuffer from collections.abc import Callable, Iterable, Iterator from os import _Opener from types import TracebackType -from typing import IO, Any, BinaryIO, TextIO +from typing import IO, Any, BinaryIO, Protocol, TextIO from typing_extensions import Literal, Self __all__ = [ @@ -144,10 +144,28 @@ class TextIOBase(IOBase): def readlines(self, __hint: int = -1) -> list[str]: ... # type: ignore[override] def read(self, __size: int | None = ...) -> str: ... +class _TextIOWrapperBuffer(Protocol): + def readable(self) -> bool: ... + def seekable(self) -> bool: ... + def writable(self) -> bool: ... + def isatty(self) -> bool: ... + def write(self, __s: bytes) -> object: ... + def flush(self) -> object: ... + def read(self, __n: int) -> ReadableBuffer: ... + def seek(self, __offset: int, __whence: int = ...) -> int: ... + def tell(self) -> int: ... + def truncate(self, __size: int | None = ...) -> int: ... + def fileno(self) -> int: ... + def close(self) -> None: ... + @property + def name(self) -> str: ... + @property + def closed(self) -> bool: ... + class TextIOWrapper(TextIOBase, TextIO): # type: ignore[misc] # incompatible definitions of write in the base classes def __init__( self, - buffer: BufferedIOBase, + buffer: _TextIOWrapperBuffer, encoding: str | None = ..., errors: str | None = ..., newline: str | None = ..., @@ -155,7 +173,7 @@ class TextIOWrapper(TextIOBase, TextIO): # type: ignore[misc] # incompatible d write_through: bool = ..., ) -> None: ... @property - def buffer(self) -> BufferedIOBase: ... # type: ignore[override] + def buffer(self) -> _TextIOWrapperBuffer: ... # type: ignore[override] @property def closed(self) -> bool: ... @property @@ -178,7 +196,7 @@ class TextIOWrapper(TextIOBase, TextIO): # type: ignore[misc] # incompatible d def writelines(self, __lines: Iterable[str]) -> None: ... # type: ignore[override] def readline(self, __size: int = -1) -> str: ... # type: ignore[override] def readlines(self, __hint: int = -1) -> list[str]: ... # type: ignore[override] - def detach(self) -> BufferedIOBase: ... # type: ignore[override] + def detach(self) -> _TextIOWrapperBuffer: ... # type: ignore[override] def seek(self, __cookie: int, __whence: int = 0) -> int: ... # stubtest needs this class StringIO(TextIOWrapper): From aafa7eddbf754557844fa6e98e8236265218fa86 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Wed, 14 Feb 2024 15:50:04 +0000 Subject: [PATCH 8/8] [pre-commit.ci] auto fixes from pre-commit.com hooks --- stdlib/io.pyi | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/stdlib/io.pyi b/stdlib/io.pyi index 39f77f451dc2..5e18a06f14cf 100644 --- a/stdlib/io.pyi +++ b/stdlib/io.pyi @@ -6,10 +6,8 @@ from _typeshed import FileDescriptorOrPath, ReadableBuffer, WriteableBuffer from collections.abc import Callable, Iterable, Iterator from os import _Opener from types import TracebackType -from typing import IO, Any, BinaryIO, Protocol, TextIO +from typing import IO, Any, BinaryIO, Literal, Protocol, TextIO, TypeVar, overload from typing_extensions import Literal, Self -from typing import IO, Any, BinaryIO, Literal, TextIO, TypeVar, overload -from typing_extensions import Self __all__ = [ "BlockingIOError",