From f24b4c8eb48a90cd63cd7469ee4855f61f95455a Mon Sep 17 00:00:00 2001 From: Sebastian Rittau Date: Tue, 18 May 2021 08:54:57 +0200 Subject: [PATCH 1/6] Remove explicit Iterable super class Use Literals for mode parameters --- stdlib/tarfile.pyi | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/stdlib/tarfile.pyi b/stdlib/tarfile.pyi index 74ebd714cf6f..8d6348647531 100644 --- a/stdlib/tarfile.pyi +++ b/stdlib/tarfile.pyi @@ -3,6 +3,7 @@ import sys from _typeshed import StrOrBytesPath, StrPath from types import TracebackType from typing import IO, Callable, Dict, Iterable, Iterator, List, Mapping, Optional, Set, Tuple, Type, Union +from typing_extensions import Literal # tar constants NUL: bytes @@ -70,10 +71,10 @@ def open( class ExFileObject(io.BufferedReader): def __init__(self, tarfile: TarFile, tarinfo: TarInfo) -> None: ... -class TarFile(Iterable[TarInfo]): +class TarFile: OPEN_METH: Mapping[str, str] name: Optional[StrOrBytesPath] - mode: str + mode: Literal["r", "a", "w"] fileobj: Optional[IO[bytes]] format: Optional[int] tarinfo: Type[TarInfo] @@ -89,7 +90,7 @@ class TarFile(Iterable[TarInfo]): def __init__( self, name: Optional[StrOrBytesPath] = ..., - mode: str = ..., + mode: Literal["r", "a", "w", "x"] = ..., fileobj: Optional[IO[bytes]] = ..., format: Optional[int] = ..., tarinfo: Optional[Type[TarInfo]] = ..., @@ -129,7 +130,7 @@ class TarFile(Iterable[TarInfo]): def taropen( cls, name: Optional[StrOrBytesPath], - mode: str = ..., + mode: Literal["r", "a", "w", "x"] = ..., fileobj: Optional[IO[bytes]] = ..., *, compresslevel: int = ..., @@ -146,7 +147,7 @@ class TarFile(Iterable[TarInfo]): def gzopen( cls, name: Optional[StrOrBytesPath], - mode: str = ..., + mode: Literal["r", "w", "x"] = ..., fileobj: Optional[IO[bytes]] = ..., compresslevel: int = ..., *, @@ -163,7 +164,7 @@ class TarFile(Iterable[TarInfo]): def bz2open( cls, name: Optional[StrOrBytesPath], - mode: str = ..., + mode: Literal["r", "w", "x"] = ..., fileobj: Optional[IO[bytes]] = ..., compresslevel: int = ..., *, @@ -180,7 +181,7 @@ class TarFile(Iterable[TarInfo]): def xzopen( cls, name: Optional[StrOrBytesPath], - mode: str = ..., + mode: Literal["r", "w", "x"] = ..., fileobj: Optional[IO[bytes]] = ..., preset: Optional[int] = ..., *, From 47fb745b9cdafbbc8d804f74dddd7d9a18217591 Mon Sep 17 00:00:00 2001 From: Sebastian Rittau Date: Tue, 18 May 2021 08:56:33 +0200 Subject: [PATCH 2/6] Import from collections.abc --- stdlib/tarfile.pyi | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/stdlib/tarfile.pyi b/stdlib/tarfile.pyi index 8d6348647531..448f6d7bc0d4 100644 --- a/stdlib/tarfile.pyi +++ b/stdlib/tarfile.pyi @@ -1,8 +1,9 @@ import io import sys +from collections.abc import Callable, Iterable, Iterator, Mapping from _typeshed import StrOrBytesPath, StrPath from types import TracebackType -from typing import IO, Callable, Dict, Iterable, Iterator, List, Mapping, Optional, Set, Tuple, Type, Union +from typing import IO, Dict, List, Optional, Set, Tuple, Type, Union from typing_extensions import Literal # tar constants From c0c64ac2d7870d9e94f9c847e0484abf23a8182b Mon Sep 17 00:00:00 2001 From: Sebastian Rittau Date: Tue, 18 May 2021 09:17:43 +0200 Subject: [PATCH 3/6] Use protocols for TarFile(fileobj=) and Tarfile.gzopen() --- stdlib/tarfile.pyi | 47 +++++++++++++++++++++++++++++++++++++--------- 1 file changed, 38 insertions(+), 9 deletions(-) diff --git a/stdlib/tarfile.pyi b/stdlib/tarfile.pyi index 448f6d7bc0d4..5a96b8338acb 100644 --- a/stdlib/tarfile.pyi +++ b/stdlib/tarfile.pyi @@ -1,11 +1,22 @@ import io import sys -from collections.abc import Callable, Iterable, Iterator, Mapping from _typeshed import StrOrBytesPath, StrPath +from collections.abc import Callable, Iterable, Iterator, Mapping +from gzip import _ReadableFileobj as _GzipReadableFileobj, _WritableFileobj as _GzipWritableFileobj from types import TracebackType -from typing import IO, Dict, List, Optional, Set, Tuple, Type, Union +from typing import IO, Any, Dict, List, Optional, Protocol, Set, Tuple, Type, Union, overload from typing_extensions import Literal +class _Fileobj(Protocol): + def read(self, __size: int) -> bytes: ... + def write(self, __b: bytes) -> Any: ... + def tell(self) -> int: ... + def seek(self, __pos: int) -> Any: ... + def close(self) -> Any: ... + # Optional fields: + # name: str | bytes + # mode: Literal["rb", "r+b", "wb", "xb"] + # tar constants NUL: bytes BLOCKSIZE: int @@ -54,7 +65,7 @@ ENCODING: str def open( name: Optional[StrOrBytesPath] = ..., mode: str = ..., - fileobj: Optional[IO[bytes]] = ..., + fileobj: Optional[IO[bytes]] = ..., # depends on mode bufsize: int = ..., *, format: Optional[int] = ..., @@ -76,7 +87,7 @@ class TarFile: OPEN_METH: Mapping[str, str] name: Optional[StrOrBytesPath] mode: Literal["r", "a", "w"] - fileobj: Optional[IO[bytes]] + fileobj: Optional[_Fileobj] format: Optional[int] tarinfo: Type[TarInfo] dereference: Optional[bool] @@ -92,7 +103,7 @@ class TarFile: self, name: Optional[StrOrBytesPath] = ..., mode: Literal["r", "a", "w", "x"] = ..., - fileobj: Optional[IO[bytes]] = ..., + fileobj: Optional[_Fileobj] = ..., format: Optional[int] = ..., tarinfo: Optional[Type[TarInfo]] = ..., dereference: Optional[bool] = ..., @@ -114,7 +125,7 @@ class TarFile: cls, name: Optional[StrOrBytesPath] = ..., mode: str = ..., - fileobj: Optional[IO[bytes]] = ..., + fileobj: Optional[IO[bytes]] = ..., # depends on mode bufsize: int = ..., *, format: Optional[int] = ..., @@ -132,7 +143,7 @@ class TarFile: cls, name: Optional[StrOrBytesPath], mode: Literal["r", "a", "w", "x"] = ..., - fileobj: Optional[IO[bytes]] = ..., + fileobj: Optional[_Fileobj] = ..., *, compresslevel: int = ..., format: Optional[int] = ..., @@ -144,12 +155,30 @@ class TarFile: debug: Optional[int] = ..., errorlevel: Optional[int] = ..., ) -> TarFile: ... + @overload @classmethod def gzopen( cls, name: Optional[StrOrBytesPath], - mode: Literal["r", "w", "x"] = ..., - fileobj: Optional[IO[bytes]] = ..., + mode: Literal["r"] = ..., + fileobj: Optional[_GzipReadableFileobj] = ..., + compresslevel: int = ..., + *, + format: Optional[int] = ..., + tarinfo: Optional[Type[TarInfo]] = ..., + dereference: Optional[bool] = ..., + ignore_zeros: Optional[bool] = ..., + encoding: Optional[str] = ..., + pax_headers: Optional[Mapping[str, str]] = ..., + debug: Optional[int] = ..., + errorlevel: Optional[int] = ..., + ) -> TarFile: ... + @classmethod + def gzopen( + cls, + name: Optional[StrOrBytesPath], + mode: Literal["w", "x"], + fileobj: Optional[_GzipWritableFileobj] = ..., compresslevel: int = ..., *, format: Optional[int] = ..., From 51690e8770f2541d73f5fc88e44c0cb9f85daaf2 Mon Sep 17 00:00:00 2001 From: Sebastian Rittau Date: Tue, 18 May 2021 09:26:39 +0200 Subject: [PATCH 4/6] Use object instead of Any as protocol return types --- stdlib/tarfile.pyi | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/stdlib/tarfile.pyi b/stdlib/tarfile.pyi index 5a96b8338acb..5bc2882d8839 100644 --- a/stdlib/tarfile.pyi +++ b/stdlib/tarfile.pyi @@ -4,15 +4,15 @@ from _typeshed import StrOrBytesPath, StrPath from collections.abc import Callable, Iterable, Iterator, Mapping from gzip import _ReadableFileobj as _GzipReadableFileobj, _WritableFileobj as _GzipWritableFileobj from types import TracebackType -from typing import IO, Any, Dict, List, Optional, Protocol, Set, Tuple, Type, Union, overload +from typing import IO, Dict, List, Optional, Protocol, Set, Tuple, Type, Union, overload from typing_extensions import Literal class _Fileobj(Protocol): def read(self, __size: int) -> bytes: ... - def write(self, __b: bytes) -> Any: ... + def write(self, __b: bytes) -> object: ... def tell(self) -> int: ... - def seek(self, __pos: int) -> Any: ... - def close(self) -> Any: ... + def seek(self, __pos: int) -> object: ... + def close(self) -> object: ... # Optional fields: # name: str | bytes # mode: Literal["rb", "r+b", "wb", "xb"] From c6b006bb34dba4db8956bebdbe4a1f2cd32a4ee0 Mon Sep 17 00:00:00 2001 From: Sebastian Rittau Date: Tue, 18 May 2021 09:52:57 +0200 Subject: [PATCH 5/6] Add missing @overload --- stdlib/tarfile.pyi | 1 + 1 file changed, 1 insertion(+) diff --git a/stdlib/tarfile.pyi b/stdlib/tarfile.pyi index 5bc2882d8839..747627e61f25 100644 --- a/stdlib/tarfile.pyi +++ b/stdlib/tarfile.pyi @@ -173,6 +173,7 @@ class TarFile: debug: Optional[int] = ..., errorlevel: Optional[int] = ..., ) -> TarFile: ... + @overload @classmethod def gzopen( cls, From 46dd83c497ea6cf82beb522045054df90f2b721c Mon Sep 17 00:00:00 2001 From: Sebastian Rittau Date: Wed, 19 May 2021 09:26:33 +0200 Subject: [PATCH 6/6] Update stdlib/tarfile.pyi Co-authored-by: Jelle Zijlstra --- stdlib/tarfile.pyi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stdlib/tarfile.pyi b/stdlib/tarfile.pyi index 747627e61f25..16f759e986e6 100644 --- a/stdlib/tarfile.pyi +++ b/stdlib/tarfile.pyi @@ -86,7 +86,7 @@ class ExFileObject(io.BufferedReader): class TarFile: OPEN_METH: Mapping[str, str] name: Optional[StrOrBytesPath] - mode: Literal["r", "a", "w"] + mode: Literal["r", "a", "w", "x"] fileobj: Optional[_Fileobj] format: Optional[int] tarinfo: Type[TarInfo]