Skip to content

Fix shutil.unpack_archive stub #6869

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

Closed
wants to merge 1 commit into from

Conversation

jpy-git
Copy link
Contributor

@jpy-git jpy-git commented Jan 8, 2022

filename argument of shutil.unpack_archive can take bytes and PathLike[bytes] (python3.6 can only take bytes).

from pathlib import Path
import shutil
from typing import AnyStr, Generic


class DummyPathLike(Generic[AnyStr]):
    """Since pathlib.Path can't accept bytes itself."""

    def __init__(self, path: AnyStr) -> None:
        self._path: AnyStr = path

    def __fspath__(self) -> AnyStr:
        """Return the file system path representation of the object."""
        return self._path

Path("some_folder").mkdir()
Path("some_folder/test.txt").touch()

shutil.make_archive(base_name="my_archive", format="gztar", root_dir="some_folder", base_dir=".")

shutil.unpack_archive(
    filename="my_archive.tar.gz",
    extract_dir="extract_folder",
    format="gztar",
)
shutil.unpack_archive(
    filename=b"my_archive.tar.gz",
    extract_dir="extract_folder",
    format="gztar",
)
shutil.unpack_archive(
    filename=Path("my_archive.tar.gz"),
    extract_dir="extract_folder",
    format="gztar",
)
shutil.unpack_archive(
    filename=DummyPathLike(b"my_archive.tar.gz"),
    extract_dir="extract_folder",
    format="gztar",
)


Path("some_folder/test.txt").unlink()
Path("my_archive.tar.gz").unlink()
Path("extract_folder/test.txt").unlink()
Path("extract_folder").rmdir()

I also checked the extract_dir argument but those still need to be strings so no change there:

# N.B. these versions below fail with TypeError: `Can't mix strings and bytes in path components`
shutil.unpack_archive(
    filename="my_archive.tar.gz",
    extract_dir=b"extract_folder",
    format="gztar",
)
shutil.unpack_archive(
    filename="my_archive.tar.gz",
    extract_dir=DummyPathLike(b"extract_folder"),
    format="gztar",
)

@github-actions
Copy link
Contributor

github-actions bot commented Jan 9, 2022

According to mypy_primer, this change has no effect on the checked open source code. 🤖🎉

@srittau
Copy link
Collaborator

srittau commented Feb 2, 2022

That doesn't look right to me in the general case. For example:

>>> import shutil
>>> shutil.unpack_archive(b"foo.zip")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python3.9/shutil.py", line 1239, in unpack_archive
    format = _find_unpack_format(filename)
  File "/usr/lib/python3.9/shutil.py", line 1202, in _find_unpack_format
    if filename.endswith(extension):
TypeError: endswith first arg must be bytes or a tuple of bytes, not str

@srittau
Copy link
Collaborator

srittau commented Feb 22, 2022

Closing per my last comment.

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.

3 participants