Skip to content

Commit c4e0580

Browse files
matthiaskrammJelleZijlstra
authored andcommitted
make io.pyi import everything from _io.py(i), like io.py does (#1395)
* make io.pyi import _io.py(i), like io.py does * make write/writelines take 'Any', on _IOBase * Add missing constructors, fix inconsistencies. * Also, as far as possible, try to simplify, by moving methods into base classes. * fix lint+mypy warnings * add missing __enter__ methods * make _IOBase inherit from BinaryIO * make _TextIOBase not subclass _IOBase
1 parent 6fe68fd commit c4e0580

2 files changed

Lines changed: 116 additions & 118 deletions

File tree

stdlib/2/_io.pyi

Lines changed: 91 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,18 @@
1-
from typing import Any, BinaryIO, IO, Iterable, Iterator, List, Optional, Type, Tuple, Union
1+
from typing import Any, AnyStr, BinaryIO, IO, Text, TextIO, Iterable, Iterator, List, Optional, Type, Tuple, TypeVar, Union
2+
from types import TracebackType
23

34
DEFAULT_BUFFER_SIZE = ... # type: int
45

5-
66
class BlockingIOError(IOError):
77
characters_written = ... # type: int
88

99
class UnsupportedOperation(ValueError, IOError): ...
1010

11+
_T = TypeVar("_T")
1112

1213
class _IOBase(BinaryIO):
14+
@property
15+
def closed(self) -> bool: ...
1316
def _checkClosed(self) -> None: ...
1417
def _checkReadable(self) -> None: ...
1518
def _checkSeekable(self) -> None: ...
@@ -19,91 +22,147 @@ class _IOBase(BinaryIO):
1922
def fileno(self) -> int: ...
2023
def flush(self) -> None: ...
2124
def isatty(self) -> bool: ...
22-
def read(self, n: int = ...) -> bytes: ...
2325
def readable(self) -> bool: ...
24-
def readline(self, limit: int = ...) -> bytes: ...
25-
def readlines(self, hint: int = ...) -> list[bytes]: ...
2626
def seek(self, offset: int, whence: int = ...) -> int: ...
2727
def seekable(self) -> bool: ...
2828
def tell(self) -> int: ...
2929
def truncate(self, size: Optional[int] = ...) -> int: ...
3030
def writable(self) -> bool: ...
31-
def write(self, s: bytes) -> int: ...
31+
def __enter__(self: _T) -> _T: ...
32+
def __exit__(self, t: Optional[Type[BaseException]], value: Optional[BaseException], traceback: Optional[Any]) -> bool: ...
33+
def __iter__(self: _T) -> _T: ...
34+
# The parameter type of writelines[s]() is determined by that of write():
3235
def writelines(self, lines: Iterable[bytes]) -> None: ...
36+
# The return type of readline[s]() and next() is determined by that of read():
37+
def readline(self, limit: int = ...) -> bytes: ...
38+
def readlines(self, hint: int = ...) -> list[bytes]: ...
3339
def next(self) -> bytes: ...
34-
def __iter__(self) -> Iterator[bytes]: ...
35-
def __enter__(self) -> '_IOBase': ...
36-
def __exit__(self, t: Optional[Type[BaseException]], value: Optional[BaseException],
37-
# TODO: traceback should be TracebackType but that's defined in types
38-
traceback: Optional[Any]) -> bool: ...
3940

4041
class _BufferedIOBase(_IOBase):
41-
def read1(self, n: int) -> str: ...
42-
def read(self, n: int = ...) -> str: ...
42+
def read1(self, n: int) -> bytes: ...
43+
def read(self, size: int = ...) -> bytes: ...
4344
def readinto(self, buffer: bytearray) -> int: ...
44-
def write(self, s: str) -> int: ...
45-
def detach(self) -> "_BufferedIOBase": ...
45+
def write(self, s: bytes) -> int: ...
46+
def detach(self) -> _IOBase: ...
4647

4748
class BufferedRWPair(_BufferedIOBase):
48-
def peek(self, n: int = ...) -> str: ...
49+
def __init__(self, reader: _RawIOBase, writer: _RawIOBase,
50+
buffer_size: int = ..., max_buffer_size: int = ...) -> None: ...
51+
def peek(self, n: int = ...) -> bytes: ...
52+
def __enter__(self) -> BufferedRWPair: ...
4953

5054
class BufferedRandom(_BufferedIOBase):
55+
mode = ... # type: str
5156
name = ... # type: str
5257
raw = ... # type: _IOBase
53-
mode = ... # type: str
54-
def peek(self, n: int = ...) -> str: ...
58+
def __init__(self, raw: _IOBase,
59+
buffer_size: int = ...,
60+
max_buffer_size: int = ...) -> None: ...
61+
def peek(self, n: int = ...) -> bytes: ...
5562

5663
class BufferedReader(_BufferedIOBase):
64+
mode = ... # type: str
5765
name = ... # type: str
5866
raw = ... # type: _IOBase
59-
mode = ... # type: str
60-
def peek(self, n: int = ...) -> str: ...
67+
def __init__(self, raw: _IOBase, buffer_size: int = ...) -> None: ...
68+
def peek(self, n: int = ...) -> bytes: ...
6169

6270
class BufferedWriter(_BufferedIOBase):
6371
name = ... # type: str
6472
raw = ... # type: _IOBase
6573
mode = ... # type: str
74+
def __init__(self, raw: _IOBase,
75+
buffer_size: int = ...,
76+
max_buffer_size: int = ...) -> None: ...
6677

6778
class BytesIO(_BufferedIOBase):
79+
def __init__(self, initial_bytes: bytes = ...) -> None: ...
6880
def __setstate__(self, tuple) -> None: ...
6981
def __getstate__(self) -> tuple: ...
70-
def getvalue(self) -> str: ...
82+
def getvalue(self) -> bytes: ...
83+
def write(self, s: bytes) -> int: ...
84+
def writelines(self, lines: Iterable[bytes]) -> None: ...
85+
def read1(self, size: int) -> bytes: ...
86+
def next(self) -> bytes: ...
7187

7288
class _RawIOBase(_IOBase):
7389
def readall(self) -> str: ...
7490
def read(self, n: int = ...) -> str: ...
7591

76-
class FileIO(_RawIOBase):
92+
class FileIO(_RawIOBase, BytesIO): # type: ignore # for __enter__
7793
mode = ... # type: str
7894
closefd = ... # type: bool
95+
def __init__(self, file: str, mode: str = ...) -> None: ...
7996
def readinto(self, buffer: bytearray)-> int: ...
8097
def write(self, pbuf: str) -> int: ...
8198

8299
class IncrementalNewlineDecoder(object):
83100
newlines = ... # type: Union[str, unicode]
101+
def __init__(self, decoder, translate, z=...) -> None: ...
84102
def decode(self, input, final) -> Any: ...
85103
def getstate(self) -> Tuple[Any, int]: ...
86104
def setstate(self, state: Tuple[Any, int]) -> None: ...
87105
def reset(self) -> None: ...
88106

89-
class _TextIOBase(_IOBase):
107+
108+
# Note: In the actual _io.py, _TextIOBase inherits from _IOBase.
109+
class _TextIOBase(TextIO):
90110
errors = ... # type: Optional[str]
91-
newlines = ... # type: Union[str, unicode]
92-
encoding = ... # type: Optional[str]
93-
def read(self, n: int = ...) -> str: ...
94-
def detach(self) -> None:
95-
raise UnsupportedOperation
111+
# TODO: On _TextIOBase, this is always None. But it's unicode/bytes in subclasses.
112+
newlines = ... # type: Union[None, unicode, bytes]
113+
encoding = ... # type: str
114+
@property
115+
def closed(self) -> bool: ...
116+
def _checkClosed(self) -> None: ...
117+
def _checkReadable(self) -> None: ...
118+
def _checkSeekable(self) -> None: ...
119+
def _checkWritable(self) -> None: ...
120+
def close(self) -> None: ...
121+
def detach(self) -> IO: ...
122+
def fileno(self) -> int: ...
123+
def flush(self) -> None: ...
124+
def isatty(self) -> bool: ...
125+
def next(self) -> unicode: ...
126+
def read(self, size: int = ...) -> unicode: ...
127+
def readable(self) -> bool: ...
128+
def readline(self, limit: int = ...) -> unicode: ...
129+
def readlines(self, hint: int = ...) -> list[unicode]: ...
130+
def seek(self, offset: int, whence: int = ...) -> int: ...
131+
def seekable(self) -> bool: ...
132+
def tell(self) -> int: ...
133+
def truncate(self, size: Optional[int] = ...) -> int: ...
134+
def writable(self) -> bool: ...
135+
def write(self, pbuf: unicode) -> int: ...
136+
def writelines(self, lines: Iterable[unicode]) -> None: ...
137+
def __enter__(self: _T) -> _T: ...
138+
def __exit__(self, t: Optional[Type[BaseException]], value: Optional[BaseException], traceback: Optional[Any]) -> bool: ...
139+
def __iter__(self: _T) -> _T: ...
96140

97141
class StringIO(_TextIOBase):
98142
line_buffering = ... # type: bool
99-
def getvalue(self) -> str: ...
143+
def __init__(self,
144+
initial_value: Optional[unicode] = ...,
145+
newline: Optional[unicode] = ...) -> None: ...
100146
def __setstate__(self, state: tuple) -> None: ...
101147
def __getstate__(self) -> tuple: ...
148+
def getvalue(self) -> unicode: ...
102149

103150
class TextIOWrapper(_TextIOBase):
104151
name = ... # type: str
105152
line_buffering = ... # type: bool
106-
buffer = ... # type: str
153+
buffer = ... # type: BinaryIO
107154
_CHUNK_SIZE = ... # type: int
108-
109-
def open(file: Union[int, str], mode: str = ...) -> _IOBase: ...
155+
def __init__(self, buffer: IO,
156+
encoding: Optional[Text] = ...,
157+
errors: Optional[Text] = ...,
158+
newline: Optional[Text] = ...,
159+
line_buffering: bool = ...,
160+
write_through: bool = ...) -> None: ...
161+
162+
def open(file: Union[str, unicode, int],
163+
mode: unicode = ...,
164+
buffering: int = ...,
165+
encoding: Optional[Text] = ...,
166+
errors: Optional[Text] = ...,
167+
newline: Optional[Text] = ...,
168+
closefd: bool = ...) -> IO[Any]: ...

stdlib/2/io.pyi

Lines changed: 25 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -7,98 +7,37 @@
77
from typing import List, BinaryIO, TextIO, IO, overload, Iterator, Iterable, Any, Union, Optional
88
import _io
99

10-
DEFAULT_BUFFER_SIZE = 0
11-
12-
def open(file: Union[str, unicode, int],
10+
from _io import BlockingIOError as BlockingIOError
11+
from _io import BufferedRWPair as BufferedRWPair
12+
from _io import BufferedRandom as BufferedRandom
13+
from _io import BufferedReader as BufferedReader
14+
from _io import BufferedWriter as BufferedWriter
15+
from _io import BytesIO as BytesIO
16+
from _io import DEFAULT_BUFFER_SIZE as DEFAULT_BUFFER_SIZE
17+
from _io import FileIO as FileIO
18+
from _io import IncrementalNewlineDecoder as IncrementalNewlineDecoder
19+
from _io import StringIO as StringIO
20+
from _io import TextIOWrapper as TextIOWrapper
21+
from _io import UnsupportedOperation as UnsupportedOperation
22+
from _io import open as open
23+
24+
def _OpenWrapper(file: Union[str, unicode, int],
1325
mode: unicode = ..., buffering: int = ..., encoding: unicode = ...,
1426
errors: unicode = ..., newline: unicode = ...,
1527
closefd: bool = ...) -> IO[Any]: ...
1628

17-
class IOBase(_io._IOBase): ...
18-
19-
class BytesIO(BinaryIO):
20-
def __init__(self, initial_bytes: str = ...) -> None: ...
21-
# TODO getbuffer
22-
# TODO see comments in BinaryIO for missing functionality
23-
def close(self) -> None: ...
24-
def closed(self) -> bool: ...
25-
def fileno(self) -> int: ...
26-
def flush(self) -> None: ...
27-
def isatty(self) -> bool: ...
28-
def read(self, n: int = ...) -> str: ...
29-
def readable(self) -> bool: ...
30-
def readline(self, limit: int = ...) -> str: ...
31-
def readlines(self, hint: int = ...) -> List[str]: ...
32-
def seek(self, offset: int, whence: int = ...) -> int: ...
33-
def seekable(self) -> bool: ...
34-
def tell(self) -> int: ...
35-
def truncate(self, size: Optional[int] = ...) -> int: ...
36-
def writable(self) -> bool: ...
37-
def write(self, s: str) -> int: ...
38-
def writelines(self, lines: Iterable[str]) -> None: ...
39-
def getvalue(self) -> str: ...
40-
def read1(self) -> str: ...
29+
SEEK_SET = ... # type: int
30+
SEEK_CUR = ... # type: int
31+
SEEK_END = ... # type: int
4132

42-
def __iter__(self) -> Iterator[str]: ...
43-
def next(self) -> str: ...
44-
def __enter__(self) -> 'BytesIO': ...
45-
def __exit__(self, type, value, traceback) -> bool: ...
4633

47-
class StringIO(TextIO):
48-
def __init__(self, initial_value: unicode = ...,
49-
newline: unicode = ...) -> None: ...
50-
# TODO see comments in BinaryIO for missing functionality
51-
name = ... # type: str
52-
def close(self) -> None: ...
53-
def closed(self) -> bool: ...
54-
def fileno(self) -> int: ...
55-
def flush(self) -> None: ...
56-
def isatty(self) -> bool: ...
57-
def read(self, n: int = ...) -> unicode: ...
58-
def readable(self) -> bool: ...
59-
def readline(self, limit: int = ...) -> unicode: ...
60-
def readlines(self, hint: int = ...) -> List[unicode]: ...
61-
def seek(self, offset: int, whence: int = ...) -> int: ...
62-
def seekable(self) -> bool: ...
63-
def tell(self) -> int: ...
64-
def truncate(self, size: Optional[int] = ...) -> int: ...
65-
def writable(self) -> bool: ...
66-
def write(self, s: unicode) -> int: ...
67-
def writelines(self, lines: Iterable[unicode]) -> None: ...
68-
def getvalue(self) -> unicode: ...
69-
70-
def __iter__(self) -> Iterator[unicode]: ...
71-
def next(self) -> unicode: ...
72-
def __enter__(self) -> 'StringIO': ...
73-
def __exit__(self, type, value, traceback) -> bool: ...
34+
class IOBase(_io._IOBase): ...
7435

75-
class TextIOWrapper(TextIO):
76-
# write_through is undocumented but used by subprocess
77-
def __init__(self, buffer: IO[str], encoding: unicode = ...,
78-
errors: unicode = ..., newline: unicode = ...,
79-
line_buffering: bool = ...,
80-
write_through: bool = ...) -> None: ...
81-
# TODO see comments in BinaryIO for missing functionality
82-
def close(self) -> None: ...
83-
def closed(self) -> bool: ...
84-
def fileno(self) -> int: ...
85-
def flush(self) -> None: ...
86-
def isatty(self) -> bool: ...
87-
def read(self, n: int = ...) -> unicode: ...
88-
def readable(self) -> bool: ...
89-
def readline(self, limit: int = ...) -> unicode: ...
90-
def readlines(self, hint: int = ...) -> List[unicode]: ...
91-
def seek(self, offset: int, whence: int = ...) -> int: ...
92-
def seekable(self) -> bool: ...
93-
def tell(self) -> int: ...
94-
def truncate(self, size: Optional[int] = ...) -> int: ...
95-
def writable(self) -> bool: ...
96-
def write(self, s: unicode) -> int: ...
97-
def writelines(self, lines: Iterable[unicode]) -> None: ...
36+
class RawIOBase(_io._RawIOBase, IOBase):
37+
pass
9838

99-
def __iter__(self) -> Iterator[unicode]: ...
100-
def next(self) -> unicode: ...
101-
def __enter__(self) -> StringIO: ...
102-
def __exit__(self, type, value, traceback) -> bool: ...
39+
class BufferedIOBase(_io._BufferedIOBase, IOBase):
40+
pass
10341

104-
class BufferedIOBase(_io._BufferedIOBase, IOBase): ...
42+
class TextIOBase(_io._TextIOBase, IOBase): # type: ignore
43+
pass

0 commit comments

Comments
 (0)