From 2f454ac589c511adb748f4e2df72addb1f9a5f2d Mon Sep 17 00:00:00 2001 From: Sebastian Rittau Date: Fri, 21 Jun 2024 11:29:46 +0200 Subject: [PATCH 1/4] `tarfile.open()`: Handle all non-pipe modes --- stdlib/tarfile.pyi | 97 ++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 90 insertions(+), 7 deletions(-) diff --git a/stdlib/tarfile.pyi b/stdlib/tarfile.pyi index 9a95db9d2c79..94c701951970 100644 --- a/stdlib/tarfile.pyi +++ b/stdlib/tarfile.pyi @@ -103,12 +103,10 @@ PAX_NAME_FIELDS: set[str] ENCODING: str -_FileCreationModes: TypeAlias = Literal["a", "w", "x"] - @overload def open( name: StrOrBytesPath | None = None, - mode: str = "r", + mode: Literal["r", "r:*", "r:", "r:gz", "r:bz2", "r:xz"] = "r", fileobj: IO[bytes] | None = None, bufsize: int = 10240, *, @@ -121,13 +119,81 @@ def open( pax_headers: Mapping[str, str] | None = ..., debug: int | None = ..., errorlevel: int | None = ..., - compresslevel: int | None = ..., - preset: Literal[0, 1, 2, 3, 4, 5, 6, 7, 8, 9] | None = ..., +) -> TarFile: ... +@overload +def open( + name: StrOrBytesPath | None, + mode: Literal["x", "x:", "a", "a:", "w", "w:"], + fileobj: _Fileobj | None = None, + bufsize: int = 10240, + *, + format: int | None = ..., + tarinfo: type[TarInfo] | None = ..., + dereference: bool | None = ..., + ignore_zeros: bool | None = ..., + encoding: str | None = ..., + errors: str = ..., + pax_headers: Mapping[str, str] | None = ..., + debug: int | None = ..., + errorlevel: int | None = ..., +) -> TarFile: ... +@overload +def open( + name: StrOrBytesPath | None = None, + *, + mode: Literal["x", "x:", "a", "a:", "w", "w:"], + fileobj: _Fileobj | None = None, + bufsize: int = 10240, + format: int | None = ..., + tarinfo: type[TarInfo] | None = ..., + dereference: bool | None = ..., + ignore_zeros: bool | None = ..., + encoding: str | None = ..., + errors: str = ..., + pax_headers: Mapping[str, str] | None = ..., + debug: int | None = ..., + errorlevel: int | None = ..., +) -> TarFile: ... +@overload +def open( + name: StrOrBytesPath | None, + mode: Literal["x:gz", "x:bz2", "w:gz", "w:bz2"], + fileobj: _Fileobj | None = None, + bufsize: int = 10240, + *, + format: int | None = ..., + tarinfo: type[TarInfo] | None = ..., + dereference: bool | None = ..., + ignore_zeros: bool | None = ..., + encoding: str | None = ..., + errors: str = ..., + pax_headers: Mapping[str, str] | None = ..., + debug: int | None = ..., + errorlevel: int | None = ..., + compresslevel: int = 9, ) -> TarFile: ... @overload def open( name: StrOrBytesPath | None = None, - mode: _FileCreationModes = ..., + *, + mode: Literal["x:gz", "x:bz2", "w:gz", "w:bz2"], + fileobj: _Fileobj | None = None, + bufsize: int = 10240, + format: int | None = ..., + tarinfo: type[TarInfo] | None = ..., + dereference: bool | None = ..., + ignore_zeros: bool | None = ..., + encoding: str | None = ..., + errors: str = ..., + pax_headers: Mapping[str, str] | None = ..., + debug: int | None = ..., + errorlevel: int | None = ..., + compresslevel: int = 9, +) -> TarFile: ... +@overload +def open( + name: StrOrBytesPath | None, + mode: Literal["x:xz", "w:xz"], fileobj: _Fileobj | None = None, bufsize: int = 10240, *, @@ -140,7 +206,24 @@ def open( pax_headers: Mapping[str, str] | None = ..., debug: int | None = ..., errorlevel: int | None = ..., - compresslevel: int | None = ..., + preset: Literal[0, 1, 2, 3, 4, 5, 6, 7, 8, 9] | None = ..., +) -> TarFile: ... +@overload +def open( + name: StrOrBytesPath | None = None, + *, + mode: Literal["x:xz", "w:xz"], + fileobj: _Fileobj | None = None, + bufsize: int = 10240, + format: int | None = ..., + tarinfo: type[TarInfo] | None = ..., + dereference: bool | None = ..., + ignore_zeros: bool | None = ..., + encoding: str | None = ..., + errors: str = ..., + pax_headers: Mapping[str, str] | None = ..., + debug: int | None = ..., + errorlevel: int | None = ..., preset: Literal[0, 1, 2, 3, 4, 5, 6, 7, 8, 9] | None = ..., ) -> TarFile: ... From 6c8faceb2be6d4c60816acb27fb87e49d9689d60 Mon Sep 17 00:00:00 2001 From: Sebastian Rittau Date: Fri, 21 Jun 2024 11:33:53 +0200 Subject: [PATCH 2/4] Add pipe modes --- stdlib/tarfile.pyi | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/stdlib/tarfile.pyi b/stdlib/tarfile.pyi index 94c701951970..4ddd704013c1 100644 --- a/stdlib/tarfile.pyi +++ b/stdlib/tarfile.pyi @@ -106,7 +106,7 @@ ENCODING: str @overload def open( name: StrOrBytesPath | None = None, - mode: Literal["r", "r:*", "r:", "r:gz", "r:bz2", "r:xz"] = "r", + mode: Literal["r", "r:*", "r:", "r:gz", "r:bz2", "r:xz", "r|*", "r|", "r|gz", "r|bz2", "r|xz"] = "r", fileobj: IO[bytes] | None = None, bufsize: int = 10240, *, @@ -123,7 +123,7 @@ def open( @overload def open( name: StrOrBytesPath | None, - mode: Literal["x", "x:", "a", "a:", "w", "w:"], + mode: Literal["x", "x:", "a", "a:", "w", "w:", "w|"], fileobj: _Fileobj | None = None, bufsize: int = 10240, *, @@ -141,7 +141,7 @@ def open( def open( name: StrOrBytesPath | None = None, *, - mode: Literal["x", "x:", "a", "a:", "w", "w:"], + mode: Literal["x", "x:", "a", "a:", "w", "w:", "w|gz"], fileobj: _Fileobj | None = None, bufsize: int = 10240, format: int | None = ..., @@ -157,7 +157,7 @@ def open( @overload def open( name: StrOrBytesPath | None, - mode: Literal["x:gz", "x:bz2", "w:gz", "w:bz2"], + mode: Literal["x:gz", "x:bz2", "w:gz", "w:bz2", "w|bz2"], fileobj: _Fileobj | None = None, bufsize: int = 10240, *, @@ -176,7 +176,7 @@ def open( def open( name: StrOrBytesPath | None = None, *, - mode: Literal["x:gz", "x:bz2", "w:gz", "w:bz2"], + mode: Literal["x:gz", "x:bz2", "w:gz", "w:bz2", "w|xz"], fileobj: _Fileobj | None = None, bufsize: int = 10240, format: int | None = ..., From 18416587c4953b4d1a2a62376e482f92277f4d21 Mon Sep 17 00:00:00 2001 From: Sebastian Rittau Date: Fri, 21 Jun 2024 11:41:00 +0200 Subject: [PATCH 3/4] Add fallback overload for pipe modes --- stdlib/tarfile.pyi | 32 +++++++++++++++++++++++++++----- 1 file changed, 27 insertions(+), 5 deletions(-) diff --git a/stdlib/tarfile.pyi b/stdlib/tarfile.pyi index 4ddd704013c1..6253eeec63bb 100644 --- a/stdlib/tarfile.pyi +++ b/stdlib/tarfile.pyi @@ -106,7 +106,7 @@ ENCODING: str @overload def open( name: StrOrBytesPath | None = None, - mode: Literal["r", "r:*", "r:", "r:gz", "r:bz2", "r:xz", "r|*", "r|", "r|gz", "r|bz2", "r|xz"] = "r", + mode: Literal["r", "r:*", "r:", "r:gz", "r:bz2", "r:xz"] = "r", fileobj: IO[bytes] | None = None, bufsize: int = 10240, *, @@ -123,7 +123,7 @@ def open( @overload def open( name: StrOrBytesPath | None, - mode: Literal["x", "x:", "a", "a:", "w", "w:", "w|"], + mode: Literal["x", "x:", "a", "a:", "w", "w:"], fileobj: _Fileobj | None = None, bufsize: int = 10240, *, @@ -141,7 +141,7 @@ def open( def open( name: StrOrBytesPath | None = None, *, - mode: Literal["x", "x:", "a", "a:", "w", "w:", "w|gz"], + mode: Literal["x", "x:", "a", "a:", "w", "w:"], fileobj: _Fileobj | None = None, bufsize: int = 10240, format: int | None = ..., @@ -157,7 +157,7 @@ def open( @overload def open( name: StrOrBytesPath | None, - mode: Literal["x:gz", "x:bz2", "w:gz", "w:bz2", "w|bz2"], + mode: Literal["x:gz", "x:bz2", "w:gz", "w:bz2"], fileobj: _Fileobj | None = None, bufsize: int = 10240, *, @@ -176,7 +176,7 @@ def open( def open( name: StrOrBytesPath | None = None, *, - mode: Literal["x:gz", "x:bz2", "w:gz", "w:bz2", "w|xz"], + mode: Literal["x:gz", "x:bz2", "w:gz", "w:bz2"], fileobj: _Fileobj | None = None, bufsize: int = 10240, format: int | None = ..., @@ -227,6 +227,28 @@ def open( preset: Literal[0, 1, 2, 3, 4, 5, 6, 7, 8, 9] | None = ..., ) -> TarFile: ... +# TODO: Temporary workaround for modes containing pipe characters. These don't +# work with mypy 1.10, but this should be fixed with mypy 1.11. +# https://github.com/python/typeshed/issues/12182 +@overload +def open( + name: StrOrBytesPath | None = None, + *, + mode: str, + fileobj: IO[bytes] | None = None, + bufsize: int = 10240, + format: int | None = ..., + tarinfo: type[TarInfo] | None = ..., + dereference: bool | None = ..., + ignore_zeros: bool | None = ..., + encoding: str | None = ..., + errors: str = ..., + pax_headers: Mapping[str, str] | None = ..., + debug: int | None = ..., + errorlevel: int | None = ..., + preset: Literal[0, 1, 2, 3, 4, 5, 6, 7, 8, 9] | None = ..., +) -> TarFile: ... + class ExFileObject(io.BufferedReader): def __init__(self, tarfile: TarFile, tarinfo: TarInfo) -> None: ... From fee21f5799bd4f5a091fefe90509859c5c3ab52f Mon Sep 17 00:00:00 2001 From: Sebastian Rittau Date: Fri, 21 Jun 2024 11:46:41 +0200 Subject: [PATCH 4/4] workaround -> fallback --- stdlib/tarfile.pyi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stdlib/tarfile.pyi b/stdlib/tarfile.pyi index 6253eeec63bb..3cbcb53e0c53 100644 --- a/stdlib/tarfile.pyi +++ b/stdlib/tarfile.pyi @@ -227,7 +227,7 @@ def open( preset: Literal[0, 1, 2, 3, 4, 5, 6, 7, 8, 9] | None = ..., ) -> TarFile: ... -# TODO: Temporary workaround for modes containing pipe characters. These don't +# TODO: Temporary fallback for modes containing pipe characters. These don't # work with mypy 1.10, but this should be fixed with mypy 1.11. # https://github.com/python/typeshed/issues/12182 @overload