From 08d210b29c7e15354faffc4ceb7c8b8186a6a5eb Mon Sep 17 00:00:00 2001 From: AT0myks Date: Fri, 22 Nov 2024 17:02:43 +0000 Subject: [PATCH 1/2] Accurate return types for `ZipFile.open()` and `zipfile.Path.open()` --- stdlib/zipfile/__init__.pyi | 35 ++++++++++++++++++++++++++++++----- stdlib/zipfile/_path.pyi | 19 +++++++++++++++---- 2 files changed, 45 insertions(+), 9 deletions(-) diff --git a/stdlib/zipfile/__init__.pyi b/stdlib/zipfile/__init__.pyi index 5b8f02f61bce..732e8876d700 100644 --- a/stdlib/zipfile/__init__.pyi +++ b/stdlib/zipfile/__init__.pyi @@ -1,6 +1,6 @@ import io import sys -from _typeshed import SizedBuffer, StrOrBytesPath, StrPath +from _typeshed import ReadableBuffer, SizedBuffer, StrOrBytesPath, StrPath from collections.abc import Callable, Iterable, Iterator from io import TextIOWrapper from os import PathLike @@ -30,7 +30,6 @@ _DateTuple = tuple[int, int, int, int, int, int] # noqa: Y026 _ZipFileMode = Literal["r", "w", "x", "a"] # noqa: Y026 _ReadWriteMode: TypeAlias = Literal["r", "w"] -_ReadWriteBinaryMode: TypeAlias = Literal["r", "w", "rb", "wb"] class BadZipFile(Exception): ... @@ -91,6 +90,12 @@ class ZipExtFile(io.BufferedIOBase): def read1(self, n: int | None) -> bytes: ... # type: ignore[override] def seek(self, offset: int, whence: int = 0) -> int: ... +class _ZipWriteFile(io.BufferedIOBase): # undocumented + def __init__(self, zf: ZipFile, zinfo: ZipInfo, zip64: bool) -> None: ... + def writable(self) -> Literal[True]: ... + def write(self, data: ReadableBuffer) -> int: ... + def close(self) -> None: ... + class _Writer(Protocol): def write(self, s: str, /) -> object: ... @@ -225,8 +230,17 @@ class ZipFile: def getinfo(self, name: str) -> ZipInfo: ... def infolist(self) -> list[ZipInfo]: ... def namelist(self) -> list[str]: ... + @overload + def open( + self, name: str | ZipInfo, mode: Literal["r"] = "r", pwd: bytes | None = None, *, force_zip64: bool = False + ) -> ZipExtFile: ... + @overload + def open( + self, name: str | ZipInfo, mode: Literal["w"] = ..., pwd: bytes | None = None, *, force_zip64: bool = False + ) -> _ZipWriteFile: ... + @overload def open( - self, name: str | ZipInfo, mode: _ReadWriteMode = "r", pwd: bytes | None = None, *, force_zip64: bool = False + self, name: str | ZipInfo, mode: _ReadWriteMode, pwd: bytes | None = None, *, force_zip64: bool = False ) -> IO[bytes]: ... def extract(self, member: str | ZipInfo, path: StrPath | None = None, pwd: bytes | None = None) -> str: ... def extractall( @@ -335,10 +349,21 @@ else: pwd: bytes | None = None, ) -> TextIOWrapper: ... @overload - def open(self, mode: Literal["rb", "wb"], *, pwd: bytes | None = None) -> IO[bytes]: ... + def open(self, mode: Literal["rb"], *, pwd: bytes | None = None) -> ZipExtFile: ... + @overload + def open(self, mode: Literal["wb"], *, pwd: bytes | None = None) -> _ZipWriteFile: ... else: + @overload + def open( + self, mode: Literal["r"] = "r", pwd: bytes | None = None, *, force_zip64: bool = False + ) -> ZipExtFile: ... + @overload + def open( + self, mode: Literal["w"] = ..., pwd: bytes | None = None, *, force_zip64: bool = False + ) -> _ZipWriteFile: ... + @overload def open( - self, mode: _ReadWriteBinaryMode = "r", pwd: bytes | None = None, *, force_zip64: bool = False + self, mode: _ReadWriteMode, pwd: bytes | None = None, *, force_zip64: bool = False ) -> IO[bytes]: ... if sys.version_info >= (3, 10): diff --git a/stdlib/zipfile/_path.pyi b/stdlib/zipfile/_path.pyi index a7248ba7ab72..83be291008b1 100644 --- a/stdlib/zipfile/_path.pyi +++ b/stdlib/zipfile/_path.pyi @@ -5,9 +5,9 @@ from io import TextIOWrapper from os import PathLike from typing import IO, Literal, TypeVar, overload from typing_extensions import Self, TypeAlias -from zipfile import ZipFile +from zipfile import _ZipWriteFile, ZipExtFile, ZipFile -_ReadWriteBinaryMode: TypeAlias = Literal["r", "w", "rb", "wb"] +_ReadWriteMode: TypeAlias = Literal["r", "w"] _ZF = TypeVar("_ZF", bound=ZipFile) @@ -64,10 +64,21 @@ if sys.version_info >= (3, 12): pwd: bytes | None = None, ) -> TextIOWrapper: ... @overload - def open(self, mode: Literal["rb", "wb"], *, pwd: bytes | None = None) -> IO[bytes]: ... + def open(self, mode: Literal["rb"], *, pwd: bytes | None = None) -> ZipExtFile: ... + @overload + def open(self, mode: Literal["wb"], *, pwd: bytes | None = None) -> _ZipWriteFile: ... else: + @overload + def open( + self, mode: Literal["r"] = "r", pwd: bytes | None = None, *, force_zip64: bool = False + ) -> ZipExtFile: ... + @overload + def open( + self, mode: Literal["w"] = ..., pwd: bytes | None = None, *, force_zip64: bool = False + ) -> _ZipWriteFile: ... + @overload def open( - self, mode: _ReadWriteBinaryMode = "r", pwd: bytes | None = None, *, force_zip64: bool = False + self, mode: _ReadWriteMode, pwd: bytes | None = None, *, force_zip64: bool = False ) -> IO[bytes]: ... if sys.version_info >= (3, 10): From 8463faf2ca9e7a112f609182d6d21d934435df76 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Fri, 22 Nov 2024 17:11:11 +0000 Subject: [PATCH 2/2] [pre-commit.ci] auto fixes from pre-commit.com hooks --- stdlib/zipfile/__init__.pyi | 12 +++--------- stdlib/zipfile/_path.pyi | 14 ++++---------- 2 files changed, 7 insertions(+), 19 deletions(-) diff --git a/stdlib/zipfile/__init__.pyi b/stdlib/zipfile/__init__.pyi index 732e8876d700..94a392df7102 100644 --- a/stdlib/zipfile/__init__.pyi +++ b/stdlib/zipfile/__init__.pyi @@ -354,17 +354,11 @@ else: def open(self, mode: Literal["wb"], *, pwd: bytes | None = None) -> _ZipWriteFile: ... else: @overload - def open( - self, mode: Literal["r"] = "r", pwd: bytes | None = None, *, force_zip64: bool = False - ) -> ZipExtFile: ... + def open(self, mode: Literal["r"] = "r", pwd: bytes | None = None, *, force_zip64: bool = False) -> ZipExtFile: ... @overload - def open( - self, mode: Literal["w"] = ..., pwd: bytes | None = None, *, force_zip64: bool = False - ) -> _ZipWriteFile: ... + def open(self, mode: Literal["w"] = ..., pwd: bytes | None = None, *, force_zip64: bool = False) -> _ZipWriteFile: ... @overload - def open( - self, mode: _ReadWriteMode, pwd: bytes | None = None, *, force_zip64: bool = False - ) -> IO[bytes]: ... + def open(self, mode: _ReadWriteMode, pwd: bytes | None = None, *, force_zip64: bool = False) -> IO[bytes]: ... if sys.version_info >= (3, 10): def iterdir(self) -> Iterator[Self]: ... diff --git a/stdlib/zipfile/_path.pyi b/stdlib/zipfile/_path.pyi index 83be291008b1..0c3b5c53e80a 100644 --- a/stdlib/zipfile/_path.pyi +++ b/stdlib/zipfile/_path.pyi @@ -5,7 +5,7 @@ from io import TextIOWrapper from os import PathLike from typing import IO, Literal, TypeVar, overload from typing_extensions import Self, TypeAlias -from zipfile import _ZipWriteFile, ZipExtFile, ZipFile +from zipfile import ZipExtFile, ZipFile, _ZipWriteFile _ReadWriteMode: TypeAlias = Literal["r", "w"] @@ -69,17 +69,11 @@ if sys.version_info >= (3, 12): def open(self, mode: Literal["wb"], *, pwd: bytes | None = None) -> _ZipWriteFile: ... else: @overload - def open( - self, mode: Literal["r"] = "r", pwd: bytes | None = None, *, force_zip64: bool = False - ) -> ZipExtFile: ... + def open(self, mode: Literal["r"] = "r", pwd: bytes | None = None, *, force_zip64: bool = False) -> ZipExtFile: ... @overload - def open( - self, mode: Literal["w"] = ..., pwd: bytes | None = None, *, force_zip64: bool = False - ) -> _ZipWriteFile: ... + def open(self, mode: Literal["w"] = ..., pwd: bytes | None = None, *, force_zip64: bool = False) -> _ZipWriteFile: ... @overload - def open( - self, mode: _ReadWriteMode, pwd: bytes | None = None, *, force_zip64: bool = False - ) -> IO[bytes]: ... + def open(self, mode: _ReadWriteMode, pwd: bytes | None = None, *, force_zip64: bool = False) -> IO[bytes]: ... if sys.version_info >= (3, 10): def iterdir(self) -> Iterator[Self]: ...