Skip to content

Conversation

kbaikov
Copy link
Contributor

@kbaikov kbaikov commented Nov 26, 2024

Fixes #12182

@srittau please take a look.

PS.
Why do you have an overload for name: StrOrBytesPath | None = None and name: StrOrBytesPath | None ?

Copy link
Contributor

Diff from mypy_primer, showing the effect of this PR on open source code:

vision (https://github.com/pytorch/vision)
+ torchvision/datasets/utils.py:215: note:     def open(name: str | bytes | PathLike[str] | PathLike[bytes] | Buffer | None = ..., *, mode: Literal['r|*', 'r|', 'r|gz', 'r|bz2', 'r|xz'], fileobj: IO[bytes] | None = ..., bufsize: int = ..., 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: int | None = ...) -> TarFile
- torchvision/datasets/utils.py:215: note:     def open(name: str | bytes | PathLike[str] | PathLike[bytes] | None = ..., *, mode: str, fileobj: IO[bytes] | None = ..., bufsize: int = ..., 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: int | None = ...) -> TarFile
+ torchvision/datasets/utils.py:215: note:     def open(name: str | bytes | PathLike[str] | PathLike[bytes] | Buffer | None = ..., *, mode: Literal['w|', 'w|gz', 'w|bz2', 'w|xz'], fileobj: IO[bytes] | None = ..., bufsize: int = ..., 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: int | None = ...) -> TarFile

pip (https://github.com/pypa/pip)
+ src/pip/_internal/utils/unpacking.py:179: note:     def open(name: str | bytes | PathLike[str] | PathLike[bytes] | Buffer | None = ..., *, mode: Literal['r|*', 'r|', 'r|gz', 'r|bz2', 'r|xz'], fileobj: IO[bytes] | None = ..., bufsize: int = ..., 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: int | None = ...) -> TarFile
- src/pip/_internal/utils/unpacking.py:179: note:     def open(name: str | bytes | PathLike[str] | PathLike[bytes] | None = ..., *, mode: str, fileobj: IO[bytes] | None = ..., bufsize: int = ..., 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: int | None = ...) -> TarFile
+ src/pip/_internal/utils/unpacking.py:179: note:     def open(name: str | bytes | PathLike[str] | PathLike[bytes] | Buffer | None = ..., *, mode: Literal['w|', 'w|gz', 'w|bz2', 'w|xz'], fileobj: IO[bytes] | None = ..., bufsize: int = ..., 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: int | None = ...) -> TarFile

@kbaikov
Copy link
Contributor Author

kbaikov commented Dec 2, 2024

@srittau could you please take a look at this PR? Not sure if i am forgetting an overload or not.

@srittau srittau merged commit fcf30cf into python:main Dec 3, 2024
63 checks passed
@srittau
Copy link
Collaborator

srittau commented Dec 3, 2024

Why do you have an overload for name: StrOrBytesPath | None = None and name: StrOrBytesPath | None ?

This is a hack, since arguments without default can't follow arguments with default. For example, we need the overload with default so that open(mode="x") is accepted. On the other hand, the overload without default is used when calling open() positionally: open("foo.tar", "x"). In that case we can't use a default for name, because we can't have a default for mode. Ideally we would just have one overload, but that is a syntax error:

@overload
def open(
    name: StrOrBytesPath | None = None,
    mode: Literal["x", "x:", "a", "a:", "w", "w:"],
    fileobj: _Fileobj | None = None,
    ...
) -> TarFile: ...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

tarfile.open(): Protocols for pipe modes

2 participants