summaryrefslogtreecommitdiffstats
path: root/contrib/python/wheel
diff options
context:
space:
mode:
authorrobot-piglet <[email protected]>2026-05-09 13:40:21 +0300
committerrobot-piglet <[email protected]>2026-05-09 14:02:07 +0300
commitc6b1136c63007d6b76522f7e4e8c088a64f3d4ef (patch)
tree32dbe4ee000ace2b930b2a89a6c135aee2739477 /contrib/python/wheel
parent6fe588367e85b9654d2452114228f40e1258e15d (diff)
Intermediate changes
commit_hash:cde485a7c8d98c5dc32a0d61f4ee2b2b9866f3c5
Diffstat (limited to 'contrib/python/wheel')
-rw-r--r--contrib/python/wheel/.dist-info/METADATA7
-rw-r--r--contrib/python/wheel/README.rst2
-rw-r--r--contrib/python/wheel/wheel/__init__.py2
-rw-r--r--contrib/python/wheel/wheel/__main__.py2
-rw-r--r--contrib/python/wheel/wheel/_commands/__init__.py16
-rw-r--r--contrib/python/wheel/wheel/_commands/info.py124
-rw-r--r--contrib/python/wheel/wheel/wheelfile.py11
-rw-r--r--contrib/python/wheel/ya.make3
8 files changed, 158 insertions, 9 deletions
diff --git a/contrib/python/wheel/.dist-info/METADATA b/contrib/python/wheel/.dist-info/METADATA
index 77936a9eb63..4824efd691b 100644
--- a/contrib/python/wheel/.dist-info/METADATA
+++ b/contrib/python/wheel/.dist-info/METADATA
@@ -1,6 +1,6 @@
Metadata-Version: 2.4
Name: wheel
-Version: 0.46.3
+Version: 0.47.0
Summary: Command line tool for manipulating wheel files
Keywords: wheel,packaging
Author-email: Daniel Holth <[email protected]>
@@ -21,13 +21,10 @@ Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
License-File: LICENSE.txt
Requires-Dist: packaging >= 24.0
-Requires-Dist: pytest >= 6.0.0 ; extra == "test"
-Requires-Dist: setuptools >= 77 ; extra == "test"
Project-URL: Changelog, https://wheel.readthedocs.io/en/stable/news.html
Project-URL: Documentation, https://wheel.readthedocs.io/
Project-URL: Issue Tracker, https://github.com/pypa/wheel/issues
Project-URL: Source, https://github.com/pypa/wheel
-Provides-Extra: test
wheel
=====
@@ -40,7 +37,7 @@ This is a command line tool for manipulating Python wheel files, as defined in
* Repack wheel archives
* Add or remove tags in existing wheel archives
-.. _PEP 427: https://www.python.org/dev/peps/pep-0427/
+.. _PEP 427: https://peps.python.org/pep-0427/
Historical note
---------------
diff --git a/contrib/python/wheel/README.rst b/contrib/python/wheel/README.rst
index ea16e65466a..cb499c9457c 100644
--- a/contrib/python/wheel/README.rst
+++ b/contrib/python/wheel/README.rst
@@ -9,7 +9,7 @@ This is a command line tool for manipulating Python wheel files, as defined in
* Repack wheel archives
* Add or remove tags in existing wheel archives
-.. _PEP 427: https://www.python.org/dev/peps/pep-0427/
+.. _PEP 427: https://peps.python.org/pep-0427/
Historical note
---------------
diff --git a/contrib/python/wheel/wheel/__init__.py b/contrib/python/wheel/wheel/__init__.py
index b5b076f05a6..0d9049b6607 100644
--- a/contrib/python/wheel/wheel/__init__.py
+++ b/contrib/python/wheel/wheel/__init__.py
@@ -1,3 +1,3 @@
from __future__ import annotations
-__version__ = "0.46.3"
+__version__ = "0.47.0"
diff --git a/contrib/python/wheel/wheel/__main__.py b/contrib/python/wheel/wheel/__main__.py
index 3c7de5fb7fd..ce9a58d3b94 100644
--- a/contrib/python/wheel/wheel/__main__.py
+++ b/contrib/python/wheel/wheel/__main__.py
@@ -9,7 +9,7 @@ from typing import NoReturn
def main() -> NoReturn: # needed for console script
- if __package__ == "":
+ if __spec__.parent == "":
# To be able to run 'python wheel-0.9.whl/wheel':
import os.path
diff --git a/contrib/python/wheel/wheel/_commands/__init__.py b/contrib/python/wheel/wheel/_commands/__init__.py
index 42f1d7ef309..c60772c671e 100644
--- a/contrib/python/wheel/wheel/_commands/__init__.py
+++ b/contrib/python/wheel/wheel/_commands/__init__.py
@@ -49,6 +49,15 @@ def tags_f(args: argparse.Namespace) -> None:
print(name)
+def info_f(args: argparse.Namespace) -> None:
+ from .info import info
+
+ try:
+ info(args.wheelfile, args.verbose)
+ except FileNotFoundError as e:
+ raise WheelError(str(e)) from e
+
+
def version_f(args: argparse.Namespace) -> None:
from .. import __version__
@@ -129,6 +138,13 @@ def parser() -> argparse.ArgumentParser:
)
tags_parser.set_defaults(func=tags_f)
+ info_parser = s.add_parser("info", help="Show information about a wheel file")
+ info_parser.add_argument("wheelfile", help="Wheel file to show information for")
+ info_parser.add_argument(
+ "--verbose", "-v", action="store_true", help="Show detailed file listing"
+ )
+ info_parser.set_defaults(func=info_f)
+
version_parser = s.add_parser("version", help="Print version and exit")
version_parser.set_defaults(func=version_f)
diff --git a/contrib/python/wheel/wheel/_commands/info.py b/contrib/python/wheel/wheel/_commands/info.py
new file mode 100644
index 00000000000..27ad47a2860
--- /dev/null
+++ b/contrib/python/wheel/wheel/_commands/info.py
@@ -0,0 +1,124 @@
+"""
+Display information about wheel files.
+"""
+
+from __future__ import annotations
+
+import email.policy
+import sys
+from email.parser import BytesParser
+from pathlib import Path
+
+from ..wheelfile import WheelFile
+
+
+def info(path: str, verbose: bool = False) -> None:
+ """Display information about a wheel file.
+
+ :param path: The path to the wheel file
+ :param verbose: Show detailed file listing
+ """
+ wheel_path = Path(path)
+ if not wheel_path.exists():
+ raise FileNotFoundError(f"Wheel file not found: {path}")
+
+ with WheelFile(path) as wf:
+ # Extract basic wheel information from filename
+ parsed = wf.parsed_filename
+ name = parsed.group("name")
+ version = parsed.group("ver")
+ build_tag = parsed.group("build")
+
+ print(f"Name: {name}")
+ print(f"Version: {version}")
+ if build_tag:
+ print(f"Build: {build_tag}")
+
+ # Read WHEEL metadata
+ try:
+ with wf.open(f"{wf.dist_info_path}/WHEEL") as wheel_file:
+ wheel_metadata = BytesParser(policy=email.policy.compat32).parse(
+ wheel_file
+ )
+
+ print(
+ f"Wheel-Version: {wheel_metadata.get('Wheel-Version', 'Unknown')}"
+ )
+ print(
+ f"Root-Is-Purelib: {wheel_metadata.get('Root-Is-Purelib', 'Unknown')}"
+ )
+
+ # Get all tags
+ tags = wheel_metadata.get_all("Tag", [])
+ if tags:
+ print("Tags:")
+ for tag in sorted(tags): # Sort tags for consistent output
+ print(f" {tag}")
+
+ generators = wheel_metadata.get_all("Generator", [])
+ for generator in generators:
+ print(f"Generator: {generator}")
+ except KeyError:
+ print("Warning: WHEEL metadata file not found", file=sys.stderr)
+
+ # Read package METADATA
+ try:
+ with wf.open(f"{wf.dist_info_path}/METADATA") as metadata_file:
+ pkg_metadata = BytesParser(policy=email.policy.compat32).parse(
+ metadata_file
+ )
+
+ summary = pkg_metadata.get("Summary", "")
+ if summary and summary != "UNKNOWN":
+ print(f"Summary: {summary}")
+
+ author = pkg_metadata.get("Author", "")
+ if author and author != "UNKNOWN":
+ print(f"Author: {author}")
+
+ author_email = pkg_metadata.get("Author-email")
+ if author_email and author_email != "UNKNOWN":
+ print(f"Author-email: {author_email}")
+
+ homepage = pkg_metadata.get("Home-page")
+ if homepage and homepage != "UNKNOWN":
+ print(f"Home-page: {homepage}")
+
+ license_info = pkg_metadata.get("License")
+ if license_info and license_info != "UNKNOWN":
+ print(f"License: {license_info}")
+
+ # Show classifiers
+ classifiers = pkg_metadata.get_all("Classifier", [])
+ if classifiers:
+ print("Classifiers:")
+ for classifier in sorted(
+ classifiers[:5]
+ ): # Sort and limit to first 5
+ print(f" {classifier}")
+
+ if len(classifiers) > 5:
+ print(f" ... and {len(classifiers) - 5} more")
+
+ # Show dependencies
+ requires_dist = pkg_metadata.get_all("Requires-Dist", [])
+ if requires_dist:
+ print("Requires-Dist:")
+ for req in sorted(requires_dist): # Sort dependencies
+ print(f" {req}")
+ except KeyError:
+ print("Warning: METADATA file not found", file=sys.stderr)
+
+ # File information
+ file_count = len(wf.filelist)
+ total_size = sum(zinfo.file_size for zinfo in wf.filelist)
+
+ print(f"Files: {file_count}")
+ print(f"Size: {total_size:,} bytes")
+
+ # Show file listing if verbose
+ if verbose:
+ print("\nFile listing:")
+ for zinfo in wf.filelist:
+ size_str = f"{zinfo.file_size:,}" if zinfo.file_size > 0 else "0"
+ print(f" {zinfo.filename:60} {size_str:>10} bytes")
diff --git a/contrib/python/wheel/wheel/wheelfile.py b/contrib/python/wheel/wheel/wheelfile.py
index 7b6fd71621b..bb96a2ac706 100644
--- a/contrib/python/wheel/wheel/wheelfile.py
+++ b/contrib/python/wheel/wheel/wheelfile.py
@@ -82,6 +82,17 @@ class WheelFile(ZipFile):
self._file_hashes: dict[str, tuple[None, None] | tuple[int, bytes]] = {}
self._file_sizes = {}
if mode == "r":
+ # The .dist-info directory inside the wheel may use normalized
+ # (lowercase) naming even when the filename does not. Resolve the
+ # actual path case-insensitively.
+ if self.record_path not in self.namelist():
+ lowered = self.dist_info_path.lower() + "/record"
+ for name in self.namelist():
+ if name.lower() == lowered:
+ self.dist_info_path = name.rsplit("/RECORD", 1)[0]
+ self.record_path = name
+ break
+
# Ignore RECORD and any embedded wheel signatures
self._file_hashes[self.record_path] = None, None
self._file_hashes[self.record_path + ".jws"] = None, None
diff --git a/contrib/python/wheel/ya.make b/contrib/python/wheel/ya.make
index 6ff4c8aeda6..b0c0af58c78 100644
--- a/contrib/python/wheel/ya.make
+++ b/contrib/python/wheel/ya.make
@@ -2,7 +2,7 @@
PY3_LIBRARY()
-VERSION(0.46.3)
+VERSION(0.47.0)
LICENSE(MIT)
@@ -19,6 +19,7 @@ PY_SRCS(
wheel/_bdist_wheel.py
wheel/_commands/__init__.py
wheel/_commands/convert.py
+ wheel/_commands/info.py
wheel/_commands/pack.py
wheel/_commands/tags.py
wheel/_commands/unpack.py