diff options
author | Alex Grönholm <alex.gronholm@nextday.fi> | 2023-03-13 22:52:37 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-03-13 22:52:37 +0200 |
commit | 934fe177ff912c8e03d5ae951d3805e1fd90ba5e (patch) | |
tree | 39933c5d9d3817cce927f46f5340a43bdaf651d6 | |
parent | 26d2e0d18830b31f42c67715b68504b50e13021c (diff) | |
download | wheel-git-934fe177ff912c8e03d5ae951d3805e1fd90ba5e.tar.gz |
Changed `wheel unpack` to honor the original permissions of files (#514)
Fixes #505.
-rw-r--r-- | docs/news.rst | 1 | ||||
-rw-r--r-- | src/wheel/cli/unpack.py | 9 | ||||
-rw-r--r-- | tests/cli/test_unpack.py | 24 |
3 files changed, 33 insertions, 1 deletions
diff --git a/docs/news.rst b/docs/news.rst index 4961729..2fbe136 100644 --- a/docs/news.rst +++ b/docs/news.rst @@ -4,6 +4,7 @@ Release Notes **UNRELEASED** - Updated vendored ``packaging`` to 23.0 +- ``wheel unpack`` now preserves the executable attribute of extracted files - Fixed spaces in platform names not being converted to underscores (PR by David Tucker) - Fixed ``RECORD`` files in generated wheels missing the regular file attribute - Fixed ``DeprecationWarning`` about the use of the deprecated ``pkg_resources`` API diff --git a/src/wheel/cli/unpack.py b/src/wheel/cli/unpack.py index c6409d4..d48840e 100644 --- a/src/wheel/cli/unpack.py +++ b/src/wheel/cli/unpack.py @@ -18,6 +18,13 @@ def unpack(path: str, dest: str = ".") -> None: namever = wf.parsed_filename.group("namever") destination = Path(dest) / namever print(f"Unpacking to: {destination}...", end="", flush=True) - wf.extractall(destination) + for zinfo in wf.filelist: + wf.extract(zinfo, destination) + + # Set permissions to the same values as they were set in the archive + # We have to do this manually due to + # https://github.com/python/cpython/issues/59999 + permissions = zinfo.external_attr >> 16 & 0o777 + destination.joinpath(zinfo.filename).chmod(permissions) print("OK") diff --git a/tests/cli/test_unpack.py b/tests/cli/test_unpack.py index e6a38bb..ae584af 100644 --- a/tests/cli/test_unpack.py +++ b/tests/cli/test_unpack.py @@ -1,6 +1,12 @@ from __future__ import annotations +import platform +import stat + +import pytest + from wheel.cli.unpack import unpack +from wheel.wheelfile import WheelFile def test_unpack(wheel_paths, tmp_path): @@ -10,3 +16,21 @@ def test_unpack(wheel_paths, tmp_path): """ for wheel_path in wheel_paths: unpack(wheel_path, str(tmp_path)) + + +@pytest.mark.skipif( + platform.system() == "Windows", reason="Windows does not support the executable bit" +) +def test_unpack_executable_bit(tmp_path): + wheel_path = tmp_path / "test-1.0-py3-none-any.whl" + script_path = tmp_path / "script" + script_path.write_bytes(b"test script") + script_path.chmod(0o755) + with WheelFile(wheel_path, "w") as wf: + wf.write(str(script_path), "nested/script") + + script_path.unlink() + script_path = tmp_path / "test-1.0" / "nested" / "script" + unpack(str(wheel_path), str(tmp_path)) + assert not script_path.is_dir() + assert stat.S_IMODE(script_path.stat().st_mode) == 0o755 |