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

@@ -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):