-
-
Notifications
You must be signed in to change notification settings - Fork 1.9k
Accurate overloads for ZipFile.__init__
#12119
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
19 commits
Select commit
Hold shift + click to select a range
c2505eb
chore: Accurate overloads for `ZipFile.__init__`
max-muoto 6eafa4e
Tweak
max-muoto 6bc28bd
Tweak
max-muoto 4cf07ab
Add test
max-muoto 7f75295
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] c9704b9
Tweaks
max-muoto 377ce76
Tweak
max-muoto aca61a7
Merge branch 'main' into accurate-zip-overloads
max-muoto 3af922f
Add missing annotations
max-muoto 0f7c9e0
Missing annotation
max-muoto d82e36f
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] 97a4a95
Use positional arguments
max-muoto a682d36
Merge branch 'main' into accurate-zip-overloads
max-muoto 0b52c6a
Address feedback
max-muoto 814ab6b
Shorten name
max-muoto 524d7d7
Fix tests
max-muoto 56d44c0
Merge branch 'main' into accurate-zip-overloads
max-muoto d98196a
Address feedback
max-muoto cc520e2
Fix
max-muoto File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,131 @@ | ||
from __future__ import annotations | ||
|
||
import io | ||
import pathlib | ||
import zipfile | ||
from typing import Literal | ||
|
||
### | ||
# Tests for `zipfile.ZipFile` | ||
### | ||
|
||
p = pathlib.Path("test.zip") | ||
|
||
|
||
class CustomPathObj: | ||
def __init__(self, path: str) -> None: | ||
self.path = path | ||
|
||
def __fspath__(self) -> str: | ||
return self.path | ||
|
||
|
||
class NonPathObj: | ||
def __init__(self, path: str) -> None: | ||
self.path = path | ||
|
||
|
||
class ReadableObj: | ||
def seek(self, offset: int, whence: int = 0) -> int: | ||
return 0 | ||
|
||
def read(self, n: int | None = -1) -> bytes: | ||
return b"test" | ||
|
||
|
||
class TellableObj: | ||
def tell(self) -> int: | ||
return 0 | ||
|
||
|
||
class WriteableObj: | ||
def close(self) -> None: | ||
pass | ||
|
||
def write(self, b: bytes) -> int: | ||
return len(b) | ||
|
||
def flush(self) -> None: | ||
pass | ||
|
||
|
||
class ReadTellableObj(ReadableObj): | ||
def tell(self) -> int: | ||
return 0 | ||
|
||
|
||
class SeekTellObj: | ||
def seek(self, offset: int, whence: int = 0) -> int: | ||
return 0 | ||
|
||
def tell(self) -> int: | ||
return 0 | ||
|
||
|
||
def write_zip(mode: Literal["r", "w", "x", "a"]) -> None: | ||
# Test any mode with `pathlib.Path` | ||
with zipfile.ZipFile(p, mode) as z: | ||
z.writestr("test.txt", "test") | ||
|
||
# Test any mode with `str` path | ||
with zipfile.ZipFile("test.zip", mode) as z: | ||
z.writestr("test.txt", "test") | ||
|
||
# Test any mode with `os.PathLike` object | ||
with zipfile.ZipFile(CustomPathObj("test.zip"), mode) as z: | ||
z.writestr("test.txt", "test") | ||
|
||
# Non-PathLike object should raise an error | ||
with zipfile.ZipFile(NonPathObj("test.zip"), mode) as z: # type: ignore | ||
z.writestr("test.txt", "test") | ||
|
||
# IO[bytes] like-obj should work for any mode. | ||
io_obj = io.BytesIO(b"This is a test") | ||
with zipfile.ZipFile(io_obj, mode) as z: | ||
z.writestr("test.txt", "test") | ||
|
||
# Readable object should not work for any mode. | ||
with zipfile.ZipFile(ReadableObj(), mode) as z: # type: ignore | ||
z.writestr("test.txt", "test") | ||
|
||
# Readable object should work for "r" mode. | ||
with zipfile.ZipFile(ReadableObj(), "r") as z: | ||
z.writestr("test.txt", "test") | ||
|
||
# Readable/tellable object should work for "a" mode. | ||
with zipfile.ZipFile(ReadTellableObj(), "a") as z: | ||
z.writestr("test.txt", "test") | ||
|
||
# If it doesn't have 'tell' method, it should raise an error. | ||
with zipfile.ZipFile(ReadableObj(), "a") as z: # type: ignore | ||
z.writestr("test.txt", "test") | ||
|
||
# Readable object should not work for "w" mode. | ||
with zipfile.ZipFile(ReadableObj(), "w") as z: # type: ignore | ||
z.writestr("test.txt", "test") | ||
|
||
# Tellable object should not work for any mode. | ||
with zipfile.ZipFile(TellableObj(), mode) as z: # type: ignore | ||
z.writestr("test.txt", "test") | ||
|
||
# Tellable object shouldn't work for "w" mode. | ||
# As `__del__` will call close. | ||
with zipfile.ZipFile(TellableObj(), "w") as z: # type: ignore | ||
z.writestr("test.txt", "test") | ||
|
||
# Writeable object should not work for any mode. | ||
with zipfile.ZipFile(WriteableObj(), mode) as z: # type: ignore | ||
z.writestr("test.txt", "test") | ||
|
||
# Writeable object should work for "w" mode. | ||
with zipfile.ZipFile(WriteableObj(), "w") as z: | ||
z.writestr("test.txt", "test") | ||
|
||
# Seekable and Tellable object should not work for any mode. | ||
with zipfile.ZipFile(SeekTellObj(), mode) as z: # type: ignore | ||
z.writestr("test.txt", "test") | ||
|
||
# Seekable and Tellable object shouldn't work for "w" mode. | ||
# Cause `__del__` will call close. | ||
with zipfile.ZipFile(SeekTellObj(), "w") as z: # type: ignore | ||
z.writestr("test.txt", "test") |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Aren't all following overloads shadowed by this one?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No - for example,
IO[bytes]
is broader than_ZipReadable
, which will lead to the second overload getting chosen if you just an object that is readable.Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As for
_ZipFileMode
, iffile
doesn't match we'll end up skipping over the overload. The tests show that this is working properly.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But that's exactly the problem. It's my understanding that overloads are processed in order (although the typing spec doesn't mention that), so
IO[bytes]
always matches before_ZipReadable
can match.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've opened python/typing#1803 for clarification.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How is that a problem though?
_ZipReadable
will get matched ifIO[bytes]
isn't fully fulfilled, or am I misunderstanding something?