From e404bc7cd6ac5fa2d6e0d632113af416b34d95c8 Mon Sep 17 00:00:00 2001 From: strager Date: Mon, 18 Jun 2018 08:29:23 -0700 Subject: [PATCH] Allow pathlib.Path in zipfile.ZipFile (#2238) `zipfile.ZipFile` is typed to accept `Text` for local and archive file paths. In Python 3.6, several `ZipFile` methods accept `pathlib.Path` objects, not just `str` objects. Generalize `ZipFile`'s methods so code using `pathlib.Path` with `ZipFile` type-checks. I verified (using my own project) that the following methods work with os.PurePath at runtime on CPython 3.6: * zipfile.ZipInfo.__init__ * zipfile.ZipInfo.extractall * zipfile.ZipInfo.write --- stdlib/2and3/zipfile.pyi | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/stdlib/2and3/zipfile.pyi b/stdlib/2and3/zipfile.pyi index 28e0f902b..9ec363154 100644 --- a/stdlib/2and3/zipfile.pyi +++ b/stdlib/2and3/zipfile.pyi @@ -2,9 +2,14 @@ from typing import Callable, IO, Iterable, List, Optional, Text, Tuple, Type, Union from types import TracebackType +import os import sys +if sys.version_info >= (3, 6): + _Path = Union[os.PathLike[Text], Text] +else: + _Path = Text _SZI = Union[Text, ZipInfo] _DT = Tuple[int, int, int, int, int, int] @@ -22,7 +27,7 @@ class ZipFile: debug = ... # type: int comment = ... # type: bytes filelist = ... # type: List[ZipInfo] - def __init__(self, file: Union[Text, IO[bytes]], mode: Text = ..., compression: int = ..., + def __init__(self, file: Union[_Path, IO[bytes]], mode: Text = ..., compression: int = ..., allowZip64: bool = ...) -> None: ... def __enter__(self) -> ZipFile: ... def __exit__(self, exc_type: Optional[Type[BaseException]], @@ -36,14 +41,14 @@ class ZipFile: pwd: Optional[bytes] = ...) -> IO[bytes]: ... def extract(self, member: _SZI, path: Optional[_SZI] = ..., pwd: bytes = ...) -> str: ... - def extractall(self, path: Optional[Text] = ..., + def extractall(self, path: Optional[_Path] = ..., members: Optional[Iterable[Text]] = ..., pwd: Optional[bytes] = ...) -> None: ... def printdir(self) -> None: ... def setpassword(self, pwd: bytes) -> None: ... def read(self, name: _SZI, pwd: Optional[bytes] = ...) -> bytes: ... def testzip(self) -> Optional[str]: ... - def write(self, filename: Text, arcname: Optional[Text] = ..., + def write(self, filename: _Path, arcname: Optional[_Path] = ..., compress_type: Optional[int] = ...) -> None: ... if sys.version_info >= (3,): def writestr(self, zinfo_or_arcname: _SZI, data: Union[bytes, str],