Skip to content

Commit 9f2a9d8

Browse files
authored
Add a typevar with a default to io.TextIOWrapper (#12286)
1 parent e8cc1e4 commit 9f2a9d8

File tree

2 files changed

+11
-10
lines changed

2 files changed

+11
-10
lines changed

stdlib/@tests/test_cases/check_io.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
from gzip import GzipFile
22
from io import FileIO, TextIOWrapper
3+
from typing_extensions import assert_type
34

4-
TextIOWrapper(FileIO(""))
5-
TextIOWrapper(FileIO(13))
6-
TextIOWrapper(GzipFile(""))
5+
assert_type(TextIOWrapper(FileIO("")).buffer, FileIO)
6+
assert_type(TextIOWrapper(FileIO(13)).detach(), FileIO)
7+
assert_type(TextIOWrapper(GzipFile("")).buffer, GzipFile)

stdlib/io.pyi

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ from _typeshed import FileDescriptorOrPath, ReadableBuffer, WriteableBuffer
66
from collections.abc import Callable, Iterable, Iterator
77
from os import _Opener
88
from types import TracebackType
9-
from typing import IO, Any, BinaryIO, Literal, Protocol, TextIO, TypeVar, overload, type_check_only
9+
from typing import IO, Any, BinaryIO, Generic, Literal, Protocol, TextIO, TypeVar, overload, type_check_only
1010
from typing_extensions import Self
1111

1212
__all__ = [
@@ -173,12 +173,12 @@ class _WrappedBuffer(Protocol):
173173
# def seek(self, offset: Literal[0], whence: Literal[2]) -> int: ...
174174
# def tell(self) -> int: ...
175175

176-
# TODO: Should be generic over the buffer type, but needs to wait for
177-
# TypeVar defaults.
178-
class TextIOWrapper(TextIOBase, TextIO): # type: ignore[misc] # incompatible definitions of write in the base classes
176+
_BufferT_co = TypeVar("_BufferT_co", bound=_WrappedBuffer, default=_WrappedBuffer, covariant=True)
177+
178+
class TextIOWrapper(TextIOBase, TextIO, Generic[_BufferT_co]): # type: ignore[misc] # incompatible definitions of write in the base classes
179179
def __init__(
180180
self,
181-
buffer: _WrappedBuffer,
181+
buffer: _BufferT_co,
182182
encoding: str | None = None,
183183
errors: str | None = None,
184184
newline: str | None = None,
@@ -187,7 +187,7 @@ class TextIOWrapper(TextIOBase, TextIO): # type: ignore[misc] # incompatible d
187187
) -> None: ...
188188
# Equals the "buffer" argument passed in to the constructor.
189189
@property
190-
def buffer(self) -> BinaryIO: ...
190+
def buffer(self) -> _BufferT_co: ... # type: ignore[override]
191191
@property
192192
def closed(self) -> bool: ...
193193
@property
@@ -211,7 +211,7 @@ class TextIOWrapper(TextIOBase, TextIO): # type: ignore[misc] # incompatible d
211211
def readline(self, size: int = -1, /) -> str: ... # type: ignore[override]
212212
def readlines(self, hint: int = -1, /) -> list[str]: ... # type: ignore[override]
213213
# Equals the "buffer" argument passed in to the constructor.
214-
def detach(self) -> BinaryIO: ...
214+
def detach(self) -> _BufferT_co: ... # type: ignore[override]
215215
# TextIOWrapper's version of seek only supports a limited subset of
216216
# operations.
217217
def seek(self, cookie: int, whence: int = 0, /) -> int: ...

0 commit comments

Comments
 (0)