Skip to content

Commit 3058bec

Browse files
make io classes inherit from typing IO classes (#4145)
This makes these classes usable if type annotations are given as "IO" or "TextIO". In the future, we'll then be able to move open() to return a concrete class instead (#3951).
1 parent de2c294 commit 3058bec

File tree

1 file changed

+24
-49
lines changed

1 file changed

+24
-49
lines changed

stdlib/3/io.pyi

Lines changed: 24 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
11
from typing import (
2-
List, BinaryIO, TextIO, Iterator, Union, Optional, Callable, Tuple, Type, Any, IO, Iterable
2+
List, BinaryIO, TextIO, Iterator, Union, Optional, Callable, Tuple, Type, Any, IO, Iterable, TypeVar
33
)
44
import builtins
55
import codecs
66
import sys
77
from mmap import mmap
88
from types import TracebackType
9-
from typing import TypeVar
109

1110
if sys.version_info >= (3, 8):
1211
from typing import Literal
@@ -85,16 +84,20 @@ class BufferedIOBase(IOBase):
8584
def read(self, __size: Optional[int] = ...) -> bytes: ...
8685
def read1(self, __size: int = ...) -> bytes: ...
8786

88-
class FileIO(RawIOBase):
87+
class FileIO(RawIOBase, BinaryIO):
8988
mode: str
90-
name: Union[int, str]
89+
# Technically this is whatever is passed in as file, either a str, a bytes, or an int.
90+
name: Union[int, str] # type: ignore
9191
def __init__(
9292
self,
9393
file: Union[str, bytes, int],
9494
mode: str = ...,
9595
closefd: bool = ...,
9696
opener: Optional[Callable[[Union[int, str], str], int]] = ...
9797
) -> None: ...
98+
def write(self, __b: bytes) -> int: ...
99+
def read(self, __size: int = ...) -> bytes: ...
100+
def __enter__(self: _T) -> _T: ...
98101

99102
class BytesIO(BufferedIOBase, BinaryIO):
100103
def __init__(self, initial_bytes: bytes = ...) -> None: ...
@@ -110,23 +113,24 @@ class BytesIO(BufferedIOBase, BinaryIO):
110113
else:
111114
def read1(self, __size: Optional[int]) -> bytes: ... # type: ignore
112115

113-
class BufferedReader(BufferedIOBase):
116+
class BufferedReader(BufferedIOBase, BinaryIO):
117+
def __enter__(self: _T) -> _T: ...
114118
def __init__(self, raw: RawIOBase, buffer_size: int = ...) -> None: ...
115119
def peek(self, __size: int = ...) -> bytes: ...
116120
if sys.version_info >= (3, 7):
117121
def read1(self, __size: int = ...) -> bytes: ...
118122
else:
119123
def read1(self, __size: int) -> bytes: ... # type: ignore
120124

121-
class BufferedWriter(BufferedIOBase):
125+
class BufferedWriter(BufferedIOBase, BinaryIO):
126+
def __enter__(self: _T) -> _T: ...
122127
def __init__(self, raw: RawIOBase, buffer_size: int = ...) -> None: ...
123-
def flush(self) -> None: ...
124128
def write(self, __buffer: Union[bytes, bytearray]) -> int: ...
125129

126130
class BufferedRandom(BufferedReader, BufferedWriter):
131+
def __enter__(self: _T) -> _T: ...
127132
def __init__(self, raw: RawIOBase, buffer_size: int = ...) -> None: ...
128133
def seek(self, __target: int, __whence: int = ...) -> int: ...
129-
def tell(self) -> int: ...
130134
if sys.version_info >= (3, 7):
131135
def read1(self, __size: int = ...) -> bytes: ...
132136
else:
@@ -144,25 +148,18 @@ class TextIOBase(IOBase):
144148
def __iter__(self) -> Iterator[str]: ... # type: ignore
145149
def __next__(self) -> str: ... # type: ignore
146150
def detach(self) -> BinaryIO: ...
147-
def write(self, s: str) -> int: ...
151+
def write(self, __s: str) -> int: ...
148152
def writelines(self, __lines: List[str]) -> None: ... # type: ignore
149-
def readline(self, size: int = ...) -> str: ... # type: ignore
153+
def readline(self, __size: int = ...) -> str: ... # type: ignore
150154
def readlines(self, __hint: int = ...) -> List[str]: ... # type: ignore
151-
def read(self, size: Optional[int] = ...) -> str: ...
152-
def seek(self, offset: int, whence: int = ...) -> int: ...
155+
def read(self, __size: Optional[int] = ...) -> str: ...
153156
def tell(self) -> int: ...
154157

155-
# TODO should extend from TextIOBase
156-
class TextIOWrapper(TextIO):
158+
class TextIOWrapper(TextIOBase, TextIO):
157159
line_buffering: bool
158-
# TODO uncomment after fixing mypy about using write_through
159-
# def __init__(self, buffer: IO[bytes], encoding: str = ...,
160-
# errors: Optional[str] = ..., newline: Optional[str] = ...,
161-
# line_buffering: bool = ..., write_through: bool = ...) \
162-
# -> None: ...
163160
def __init__(
164161
self,
165-
buffer: BinaryIO,
162+
buffer: IO[bytes],
166163
encoding: Optional[str] = ...,
167164
errors: Optional[str] = ...,
168165
newline: Optional[str] = ...,
@@ -181,36 +178,15 @@ class TextIOWrapper(TextIO):
181178
line_buffering: Optional[bool] = ...,
182179
write_through: Optional[bool] = ...
183180
) -> None: ...
184-
# copied from IOBase
185-
def __exit__(self, t: Optional[Type[BaseException]] = ..., value: Optional[BaseException] = ...,
186-
traceback: Optional[TracebackType] = ...) -> Optional[bool]: ...
187-
def close(self) -> None: ...
188-
def fileno(self) -> int: ...
189-
def flush(self) -> None: ...
190-
def isatty(self) -> bool: ...
191-
def readable(self) -> bool: ...
192-
def readlines(self, __hint: int = ...) -> List[str]: ...
193-
def seekable(self) -> bool: ...
194-
def truncate(self, __size: Optional[int] = ...) -> int: ...
195-
def writable(self) -> bool: ...
196-
# TODO should be the next line instead
197-
# def writelines(self, lines: List[str]) -> None: ...
198-
def writelines(self, __lines: Any) -> None: ...
199-
def __del__(self) -> None: ...
200181
closed: bool
201-
# copied from TextIOBase
202-
encoding: str
203-
errors: Optional[str]
204-
newlines: Union[str, Tuple[str, ...], None]
205-
def __iter__(self) -> Iterator[str]: ...
206-
def __next__(self) -> str: ...
207-
def __enter__(self) -> TextIO: ...
208-
def detach(self) -> BinaryIO: ...
209-
def write(self, __text: str) -> int: ...
210-
def readline(self, __size: int = ...) -> str: ...
211-
def read(self, __size: Optional[int] = ...) -> str: ...
182+
# These are inherited from TextIOBase, but must exist in the stub to satisfy mypy.
183+
def __enter__(self: _T) -> _T: ...
184+
def __iter__(self) -> Iterator[str]: ... # type: ignore
185+
def __next__(self) -> str: ... # type: ignore
186+
def writelines(self, __lines: List[str]) -> None: ... # type: ignore
187+
def readline(self, __size: int = ...) -> str: ... # type: ignore
188+
def readlines(self, __hint: int = ...) -> List[str]: ... # type: ignore
212189
def seek(self, __cookie: int, __whence: int = ...) -> int: ...
213-
def tell(self) -> int: ...
214190

215191
class StringIO(TextIOWrapper):
216192
def __init__(self, initial_value: Optional[str] = ...,
@@ -220,7 +196,6 @@ class StringIO(TextIOWrapper):
220196
# as a read-only property on IO[].
221197
name: Any
222198
def getvalue(self) -> str: ...
223-
def __enter__(self) -> StringIO: ...
224199

225200
class IncrementalNewlineDecoder(codecs.IncrementalDecoder):
226201
def __init__(self, decoder: Optional[codecs.IncrementalDecoder],

0 commit comments

Comments
 (0)