More precise return types for open(), Path.open(), bz2.open(), etc. (#3371)

Co-authored-by: Jelle Zijlstra <jelle.zijlstra@gmail.com>
Co-authored-by: Sebastian Rittau <srittau@rittau.biz>
This commit is contained in:
Ilaï Deutel
2020-05-28 09:20:23 -07:00
committed by GitHub
parent adafaf1964
commit 846d922df2
9 changed files with 321 additions and 75 deletions

View File

@@ -5,12 +5,13 @@ from typing import (
TypeVar, Iterator, Iterable, NoReturn, overload, Container,
Sequence, MutableSequence, Mapping, MutableMapping, Tuple, List, Any, Dict, Callable, Generic,
Set, AbstractSet, FrozenSet, MutableSet, Sized, Reversible, SupportsInt, SupportsFloat, SupportsAbs,
SupportsComplex, IO, BinaryIO, Union,
SupportsComplex, IO, BinaryIO, TextIO, Union,
ItemsView, KeysView, ValuesView, ByteString, Optional, AnyStr, Type, Text,
Protocol,
)
from abc import abstractmethod, ABCMeta
from ast import mod, AST
from io import _OpenBinaryMode, _OpenTextMode
from types import TracebackType, CodeType
import sys
@@ -1357,14 +1358,47 @@ def next(__i: Iterator[_T]) -> _T: ...
def next(__i: Iterator[_T], default: _VT) -> Union[_T, _VT]: ...
def oct(__number: Union[int, _SupportsIndex]) -> str: ...
if sys.version_info >= (3, 6):
def open(file: Union[str, bytes, int, _PathLike[Any]], mode: str = ..., buffering: int = ..., encoding: Optional[str] = ...,
errors: Optional[str] = ..., newline: Optional[str] = ..., closefd: bool = ...,
opener: Optional[Callable[[str, int], int]] = ...) -> IO[Any]: ...
elif sys.version_info >= (3,):
def open(file: Union[str, bytes, int], mode: str = ..., buffering: int = ..., encoding: Optional[str] = ...,
errors: Optional[str] = ..., newline: Optional[str] = ..., closefd: bool = ...,
opener: Optional[Callable[[str, int], int]] = ...) -> IO[Any]: ...
if sys.version_info >= (3,):
if sys.version_info >= (3, 6):
# Changed in version 3.6: Support added to accept objects implementing os.PathLike.
_OpenFile = Union[str, bytes, int, _PathLike[Any]]
else:
_OpenFile = Union[str, bytes, int]
@overload
def open(
file: _OpenFile,
mode: _OpenTextMode = ...,
buffering: int = ...,
encoding: Optional[str] = ...,
errors: Optional[str] = ...,
newline: Optional[str] = ...,
closefd: bool = ...,
opener: Optional[Callable[[str, int], int]] = ...,
) -> TextIO: ...
@overload
def open(
file: _OpenFile,
mode: _OpenBinaryMode,
buffering: int = ...,
encoding: None = ...,
errors: None = ...,
newline: None = ...,
closefd: bool = ...,
opener: Optional[Callable[[str, int], int]] = ...,
) -> BinaryIO: ...
@overload
def open(
file: _OpenFile,
mode: str,
buffering: int = ...,
encoding: Optional[str] = ...,
errors: Optional[str] = ...,
newline: Optional[str] = ...,
closefd: bool = ...,
opener: Optional[Callable[[str, int], int]] = ...,
) -> IO[Any]: ...
else:
def open(name: Union[unicode, int], mode: unicode = ..., buffering: int = ...) -> BinaryIO: ...

View File

@@ -5,6 +5,7 @@
# Only a subset of functionality is included.
from typing import List, BinaryIO, TextIO, IO, overload, Iterator, Iterable, Any, Union, Optional
from typing_extensions import Literal
import _io
from _io import BlockingIOError as BlockingIOError
@@ -21,6 +22,19 @@ from _io import TextIOWrapper as TextIOWrapper
from _io import UnsupportedOperation as UnsupportedOperation
from _io import open as open
_OpenTextMode = Literal[
'r', 'r+', '+r', 'rt', 'tr', 'rt+', 'r+t', '+rt', 'tr+', 't+r', '+tr',
'w', 'w+', '+w', 'wt', 'tw', 'wt+', 'w+t', '+wt', 'tw+', 't+w', '+tw',
'a', 'a+', '+a', 'at', 'ta', 'at+', 'a+t', '+at', 'ta+', 't+a', '+ta',
'U', 'rU', 'Ur', 'rtU', 'rUt', 'Urt', 'trU', 'tUr', 'Utr',
]
_OpenBinaryMode = Literal[
'rb', 'br', 'rb+', 'r+b', '+rb', 'br+', 'b+r', '+br',
'wb', 'bw', 'wb+', 'w+b', '+wb', 'bw+', 'b+w', '+bw',
'ab', 'ba', 'ab+', 'a+b', '+ab', 'ba+', 'b+a', '+ba',
'rbU', 'rUb', 'Urb', 'brU', 'bUr', 'Ubr',
]
def _OpenWrapper(file: Union[str, unicode, int],
mode: unicode = ..., buffering: int = ..., encoding: unicode = ...,
errors: unicode = ..., newline: unicode = ...,

View File

@@ -5,12 +5,13 @@ from typing import (
TypeVar, Iterator, Iterable, NoReturn, overload, Container,
Sequence, MutableSequence, Mapping, MutableMapping, Tuple, List, Any, Dict, Callable, Generic,
Set, AbstractSet, FrozenSet, MutableSet, Sized, Reversible, SupportsInt, SupportsFloat, SupportsAbs,
SupportsComplex, IO, BinaryIO, Union,
SupportsComplex, IO, BinaryIO, TextIO, Union,
ItemsView, KeysView, ValuesView, ByteString, Optional, AnyStr, Type, Text,
Protocol,
)
from abc import abstractmethod, ABCMeta
from ast import mod, AST
from io import _OpenBinaryMode, _OpenTextMode
from types import TracebackType, CodeType
import sys
@@ -1357,14 +1358,47 @@ def next(__i: Iterator[_T]) -> _T: ...
def next(__i: Iterator[_T], default: _VT) -> Union[_T, _VT]: ...
def oct(__number: Union[int, _SupportsIndex]) -> str: ...
if sys.version_info >= (3, 6):
def open(file: Union[str, bytes, int, _PathLike[Any]], mode: str = ..., buffering: int = ..., encoding: Optional[str] = ...,
errors: Optional[str] = ..., newline: Optional[str] = ..., closefd: bool = ...,
opener: Optional[Callable[[str, int], int]] = ...) -> IO[Any]: ...
elif sys.version_info >= (3,):
def open(file: Union[str, bytes, int], mode: str = ..., buffering: int = ..., encoding: Optional[str] = ...,
errors: Optional[str] = ..., newline: Optional[str] = ..., closefd: bool = ...,
opener: Optional[Callable[[str, int], int]] = ...) -> IO[Any]: ...
if sys.version_info >= (3,):
if sys.version_info >= (3, 6):
# Changed in version 3.6: Support added to accept objects implementing os.PathLike.
_OpenFile = Union[str, bytes, int, _PathLike[Any]]
else:
_OpenFile = Union[str, bytes, int]
@overload
def open(
file: _OpenFile,
mode: _OpenTextMode = ...,
buffering: int = ...,
encoding: Optional[str] = ...,
errors: Optional[str] = ...,
newline: Optional[str] = ...,
closefd: bool = ...,
opener: Optional[Callable[[str, int], int]] = ...,
) -> TextIO: ...
@overload
def open(
file: _OpenFile,
mode: _OpenBinaryMode,
buffering: int = ...,
encoding: None = ...,
errors: None = ...,
newline: None = ...,
closefd: bool = ...,
opener: Optional[Callable[[str, int], int]] = ...,
) -> BinaryIO: ...
@overload
def open(
file: _OpenFile,
mode: str,
buffering: int = ...,
encoding: Optional[str] = ...,
errors: Optional[str] = ...,
newline: Optional[str] = ...,
closefd: bool = ...,
opener: Optional[Callable[[str, int], int]] = ...,
) -> IO[Any]: ...
else:
def open(name: Union[unicode, int], mode: unicode = ..., buffering: int = ...) -> BinaryIO: ...

View File

@@ -1,25 +1,48 @@
import io
import sys
from typing import Any, IO, Optional, Union
from os.path import _PathType
from typing import IO, Any, Optional, TextIO, Union, overload
if sys.version_info >= (3, 6):
from os import PathLike
_PathOrFile = Union[str, bytes, IO[Any], PathLike[Any]]
elif sys.version_info >= (3, 3):
_PathOrFile = Union[str, bytes, IO[Any]]
if sys.version_info >= (3, 8):
from typing import Literal
else:
_PathOrFile = str
from typing_extensions import Literal
_PathOrFile = Union[_PathType, IO[bytes]]
def compress(data: bytes, compresslevel: int = ...) -> bytes: ...
def decompress(data: bytes) -> bytes: ...
if sys.version_info >= (3, 3):
def open(filename: _PathOrFile,
mode: str = ...,
compresslevel: int = ...,
encoding: Optional[str] = ...,
errors: Optional[str] = ...,
newline: Optional[str] = ...) -> IO[Any]: ...
_OpenBinaryMode = Literal["r", "rb", "w", "wb", "x", "xb", "a", "ab"]
_OpenTextMode = Literal["rt", "wt", "xt", "at"]
@overload
def open(
filename: _PathOrFile,
mode: _OpenBinaryMode = ...,
compresslevel: int = ...,
encoding: None = ...,
errors: None = ...,
newline: None = ...,
) -> BZ2File: ...
@overload
def open(
filename: _PathType,
mode: _OpenTextMode,
compresslevel: int = ...,
encoding: Optional[str] = ...,
errors: Optional[str] = ...,
newline: Optional[str] = ...,
) -> TextIO: ...
@overload
def open(
filename: _PathOrFile,
mode: str,
compresslevel: int = ...,
encoding: Optional[str] = ...,
errors: Optional[str] = ...,
newline: Optional[str] = ...,
) -> Union[BZ2File, TextIO]: ...
class BZ2File(io.BufferedIOBase, IO[bytes]): # type: ignore # python/mypy#5027
if sys.version_info >= (3, 9):

View File

@@ -1,10 +1,45 @@
from typing import Any, IO, Optional
from os.path import _PathType
import _compression
import sys
import zlib
from os.path import _PathType
from typing import IO, Optional, TextIO, Union, overload
def open(filename, mode: str = ..., compresslevel: int = ..., encoding: Optional[str] = ..., errors: Optional[str] = ..., newline: Optional[str] = ...) -> IO[Any]: ...
import _compression
if sys.version_info >= (3, 8):
from typing import Literal
else:
from typing_extensions import Literal
_OpenBinaryMode = Literal["r", "rb", "a", "ab", "w", "wb", "x", "xb"]
_OpenTextMode = Literal["rt", "at", "wt", "xt"]
@overload
def open(
filename: Union[_PathType, IO[bytes]],
mode: _OpenBinaryMode = ...,
compresslevel: int = ...,
encoding: None = ...,
errors: None = ...,
newline: None = ...,
) -> GzipFile: ...
@overload
def open(
filename: _PathType,
mode: _OpenTextMode,
compresslevel: int = ...,
encoding: Optional[str] = ...,
errors: Optional[str] = ...,
newline: Optional[str] = ...,
) -> TextIO: ...
@overload
def open(
filename: Union[_PathType, IO[bytes]],
mode: str,
compresslevel: int = ...,
encoding: Optional[str] = ...,
errors: Optional[str] = ...,
newline: Optional[str] = ...,
) -> Union[GzipFile, TextIO]: ...
class _PaddedFile:
file: IO[bytes]
@@ -20,7 +55,14 @@ class GzipFile(_compression.BaseStream):
name: str
compress: zlib._Compress
fileobj: IO[bytes]
def __init__(self, filename: Optional[_PathType] = ..., mode: Optional[str] = ..., compresslevel: int = ..., fileobj: Optional[IO[bytes]] = ..., mtime: Optional[float] = ...) -> None: ...
def __init__(
self,
filename: Optional[_PathType] = ...,
mode: Optional[str] = ...,
compresslevel: int = ...,
fileobj: Optional[IO[bytes]] = ...,
mtime: Optional[float] = ...,
) -> None: ...
@property
def filename(self) -> str: ...
@property
@@ -48,6 +90,8 @@ class _GzipReader(_compression.DecompressReader):
if sys.version_info >= (3, 8):
def compress(data, compresslevel: int = ..., *, mtime: Optional[float] = ...) -> bytes: ...
else:
def compress(data, compresslevel: int = ...) -> bytes: ...
def decompress(data: bytes) -> bytes: ...

View File

@@ -8,6 +8,11 @@ from mmap import mmap
from types import TracebackType
from typing import TypeVar
if sys.version_info >= (3, 8):
from typing import Literal
else:
from typing_extensions import Literal
_bytearray_like = Union[bytearray, mmap]
DEFAULT_BUFFER_SIZE: int
@@ -18,6 +23,21 @@ SEEK_END: int
_T = TypeVar('_T', bound=IOBase)
_OpenTextMode = Literal[
'r', 'r+', '+r', 'rt', 'tr', 'rt+', 'r+t', '+rt', 'tr+', 't+r', '+tr',
'w', 'w+', '+w', 'wt', 'tw', 'wt+', 'w+t', '+wt', 'tw+', 't+w', '+tw',
'a', 'a+', '+a', 'at', 'ta', 'at+', 'a+t', '+at', 'ta+', 't+a', '+ta',
'x', 'x+', '+x', 'xt', 'tx', 'xt+', 'x+t', '+xt', 'tx+', 't+x', '+tx',
'U', 'rU', 'Ur', 'rtU', 'rUt', 'Urt', 'trU', 'tUr', 'Utr',
]
_OpenBinaryMode = Literal[
'rb', 'br', 'rb+', 'r+b', '+rb', 'br+', 'b+r', '+br',
'wb', 'bw', 'wb+', 'w+b', '+wb', 'bw+', 'b+w', '+bw',
'ab', 'ba', 'ab+', 'a+b', '+ab', 'ba+', 'b+a', '+ba',
'xb', 'bx', 'xb+', 'x+b', '+xb', 'bx+', 'b+x', '+bx',
'rbU', 'rUb', 'Urb', 'brU', 'bUr', 'Ubr',
]
open = builtins.open
if sys.version_info >= (3, 8):

View File

@@ -1,12 +1,17 @@
import io
import sys
from typing import Any, IO, Mapping, Optional, Sequence, Union
from os.path import _PathType
from typing import IO, Any, Mapping, Optional, Sequence, TextIO, Union, overload
if sys.version_info >= (3, 6):
from os import PathLike
_PathOrFile = Union[str, bytes, IO[Any], PathLike[Any]]
if sys.version_info >= (3, 8):
from typing import Literal
else:
_PathOrFile = Union[str, bytes, IO[Any]]
from typing_extensions import Literal
_OpenBinaryWritingMode = Literal["w", "wb", "x", "xb", "a", "ab"]
_OpenTextWritingMode = Literal["wt", "xt", "at"]
_PathOrFile = Union[_PathType, IO[bytes]]
_FilterChain = Sequence[Mapping[str, Any]]
@@ -41,7 +46,9 @@ PRESET_EXTREME: int
# from _lzma.c
class LZMADecompressor(object):
def __init__(self, format: Optional[int] = ..., memlimit: Optional[int] = ..., filters: Optional[_FilterChain] = ...) -> None: ...
def __init__(
self, format: Optional[int] = ..., memlimit: Optional[int] = ..., filters: Optional[_FilterChain] = ...
) -> None: ...
def decompress(self, data: bytes, max_length: int = ...) -> bytes: ...
@property
def check(self) -> int: ...
@@ -54,27 +61,25 @@ class LZMADecompressor(object):
# from _lzma.c
class LZMACompressor(object):
def __init__(self,
format: Optional[int] = ...,
check: int = ...,
preset: Optional[int] = ...,
filters: Optional[_FilterChain] = ...) -> None: ...
def __init__(
self, format: Optional[int] = ..., check: int = ..., preset: Optional[int] = ..., filters: Optional[_FilterChain] = ...
) -> None: ...
def compress(self, data: bytes) -> bytes: ...
def flush(self) -> bytes: ...
class LZMAError(Exception): ...
class LZMAFile(io.BufferedIOBase, IO[bytes]): # type: ignore # python/mypy#5027
def __init__(self,
filename: Optional[_PathOrFile] = ...,
mode: str = ...,
*,
format: Optional[int] = ...,
check: int = ...,
preset: Optional[int] = ...,
filters: Optional[_FilterChain] = ...) -> None: ...
def __init__(
self,
filename: Optional[_PathOrFile] = ...,
mode: str = ...,
*,
format: Optional[int] = ...,
check: int = ...,
preset: Optional[int] = ...,
filters: Optional[_FilterChain] = ...,
) -> None: ...
def close(self) -> None: ...
@property
def closed(self) -> bool: ...
@@ -90,17 +95,73 @@ class LZMAFile(io.BufferedIOBase, IO[bytes]): # type: ignore # python/mypy#502
def seek(self, offset: int, whence: int = ...) -> int: ...
def tell(self) -> int: ...
def open(filename: _PathOrFile,
mode: str = ...,
*,
format: Optional[int] = ...,
check: int = ...,
preset: Optional[int] = ...,
filters: Optional[_FilterChain] = ...,
encoding: Optional[str] = ...,
errors: Optional[str] = ...,
newline: Optional[str] = ...) -> IO[Any]: ...
def compress(data: bytes, format: int = ..., check: int = ..., preset: Optional[int] = ..., filters: Optional[_FilterChain] = ...) -> bytes: ...
@overload
def open(
filename: _PathOrFile,
mode: Literal["r", "rb"] = ...,
*,
format: Optional[int] = ...,
check: Literal[-1] = ...,
preset: None = ...,
filters: Optional[_FilterChain] = ...,
encoding: None = ...,
errors: None = ...,
newline: None = ...,
) -> LZMAFile: ...
@overload
def open(
filename: _PathOrFile,
mode: _OpenBinaryWritingMode,
*,
format: Optional[int] = ...,
check: int = ...,
preset: Optional[int] = ...,
filters: Optional[_FilterChain] = ...,
encoding: None = ...,
errors: None = ...,
newline: None = ...,
) -> LZMAFile: ...
@overload
def open(
filename: _PathType,
mode: Literal["rt"],
*,
format: Optional[int] = ...,
check: Literal[-1] = ...,
preset: None = ...,
filters: Optional[_FilterChain] = ...,
encoding: Optional[str] = ...,
errors: Optional[str] = ...,
newline: Optional[str] = ...,
) -> TextIO: ...
@overload
def open(
filename: _PathType,
mode: _OpenTextWritingMode,
*,
format: Optional[int] = ...,
check: int = ...,
preset: Optional[int] = ...,
filters: Optional[_FilterChain] = ...,
encoding: Optional[str] = ...,
errors: Optional[str] = ...,
newline: Optional[str] = ...,
) -> TextIO: ...
@overload
def open(
filename: _PathOrFile,
mode: str,
*,
format: Optional[int] = ...,
check: int = ...,
preset: Optional[int] = ...,
filters: Optional[_FilterChain] = ...,
encoding: Optional[str] = ...,
errors: Optional[str] = ...,
newline: Optional[str] = ...,
) -> Union[LZMAFile, TextIO]: ...
def compress(
data: bytes, format: int = ..., check: int = ..., preset: Optional[int] = ..., filters: Optional[_FilterChain] = ...
) -> bytes: ...
def decompress(data: bytes, format: int = ..., memlimit: Optional[int] = ..., filters: Optional[_FilterChain] = ...) -> bytes: ...
def is_check_supported(check: int) -> bool: ...

View File

@@ -1,4 +1,6 @@
from typing import Any, Generator, IO, Optional, Sequence, Tuple, Type, TypeVar, Union, List
from io import _OpenBinaryMode, _OpenTextMode
from typing import (Any, BinaryIO, Generator, IO, List, Optional, Sequence,
TextIO, Tuple, Type, TypeVar, Union, overload)
from types import TracebackType
import os
import sys
@@ -93,8 +95,14 @@ class Path(PurePath):
else:
def mkdir(self, mode: int = ..., parents: bool = ...,
exist_ok: bool = ...) -> None: ...
def open(self, mode: str = ..., buffering: int = ...,
encoding: Optional[str] = ..., errors: Optional[str] = ...,
@overload
def open(self, mode: _OpenTextMode = ..., buffering: int = ..., encoding: Optional[str] = ..., errors: Optional[str] = ...,
newline: Optional[str] = ...) -> TextIO: ...
@overload
def open(self, mode: _OpenBinaryMode, buffering: int = ..., encoding: None = ..., errors: None = ...,
newline: None = ...) -> BinaryIO: ...
@overload
def open(self, mode: str, buffering: int = ..., encoding: Optional[str] = ..., errors: Optional[str] = ...,
newline: Optional[str] = ...) -> IO[Any]: ...
def owner(self) -> str: ...
if sys.version_info >= (3, 8):

View File

@@ -1,4 +1,6 @@
from typing import Any, Generator, IO, Optional, Sequence, Tuple, Type, TypeVar, Union, List
from io import _OpenBinaryMode, _OpenTextMode
from typing import (Any, BinaryIO, Generator, IO, List, Optional, Sequence,
TextIO, Tuple, Type, TypeVar, Union, overload)
from types import TracebackType
import os
import sys
@@ -93,8 +95,14 @@ class Path(PurePath):
else:
def mkdir(self, mode: int = ..., parents: bool = ...,
exist_ok: bool = ...) -> None: ...
def open(self, mode: str = ..., buffering: int = ...,
encoding: Optional[str] = ..., errors: Optional[str] = ...,
@overload
def open(self, mode: _OpenTextMode = ..., buffering: int = ..., encoding: Optional[str] = ..., errors: Optional[str] = ...,
newline: Optional[str] = ...) -> TextIO: ...
@overload
def open(self, mode: _OpenBinaryMode, buffering: int = ..., encoding: None = ..., errors: None = ...,
newline: None = ...) -> BinaryIO: ...
@overload
def open(self, mode: str, buffering: int = ..., encoding: Optional[str] = ..., errors: Optional[str] = ...,
newline: Optional[str] = ...) -> IO[Any]: ...
def owner(self) -> str: ...
if sys.version_info >= (3, 8):