Skip to content

more checks, less bagages #1621

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 1 commit into from
May 29, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion winpython/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,6 @@
OTHER DEALINGS IN THE SOFTWARE.
"""

__version__ = '16.1.20250525'
__version__ = '16.2.20250529'
__license__ = __doc__
__project_url__ = 'http://winpython.github.io/'
2 changes: 1 addition & 1 deletion winpython/piptree.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
from pip._vendor.packaging.markers import Marker
from importlib.metadata import Distribution, distributions
from pathlib import Path
from winpython import utils
from . import utils

logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
Expand Down
2 changes: 0 additions & 2 deletions winpython/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,6 @@
import re
import tarfile
import zipfile
import atexit
import winreg

# SOURCE_PATTERN defines what an acceptable source package name is
SOURCE_PATTERN = r'([a-zA-Z0-9\-\_\.]*)-([0-9\.\_]*[a-z]*[\-]?[0-9]*)(\.zip|\.tar\.gz|\-(py[2-7]*|py[2-7]*\.py[2-7]*)\-none\-any\.whl)'
Expand Down
54 changes: 43 additions & 11 deletions winpython/wheelhouse.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
from email.policy import default
from . import utils

from packaging.utils import canonicalize_name
from packaging.utils import canonicalize_name, parse_wheel_filename, parse_sdist_filename

# Use tomllib if available (Python 3.11+), otherwise fall back to tomli
try:
Expand Down Expand Up @@ -193,32 +193,64 @@ def get_pylock_wheels(wheelhouse: Path, lockfile: Path, wheelorigin: Optional[Pa
print(f"\n\n*** We can't install {filename} ! ***\n\n")

def extract_metadata_from_wheel(filepath: Path) -> Optional[Tuple[str, str, str]]:
"get metadata from a wheel package"
"Extract package metadata from a .whl file and validate it matches the filename"
wheel_name = filepath.name
try:
name, version, build, tags = parse_wheel_filename(wheel_name)
filename_name = canonicalize_name(name)
filename_version = str(version)
except Exception as e:
print(f"❌ Could not parse filename: {wheel_name}", e)
return None

with zipfile.ZipFile(filepath, 'r') as z:
# Locate *.dist-info/METADATA file inside but not in a vendored directory (flit-core)
for name in z.namelist():
if name.endswith(r'.dist-info/METADATA') and name.split("/")[1] == "METADATA":
with z.open(name) as meta_file:
metadata = BytesParser(policy=default).parse(meta_file)
name = canonicalize_name(str(metadata.get('Name', 'unknown'))) # Avoid Head type
version = str(metadata.get('Version', 'unknown'))
meta_name = canonicalize_name(str(metadata.get('Name', 'unknown'))) # Avoid Head type
meta_version = str(metadata.get('Version', 'unknown'))
summary = utils.sum_up(str(metadata.get('Summary', '')))
return name, version, summary
# Assert consistency
if meta_name != filename_name or meta_version != filename_version:
print(f"⚠️ Mismatch in {wheel_name}: filename says {filename_name}=={filename_version}, "
f"but METADATA says {meta_name}=={meta_version}")
return None
return meta_name, meta_version , summary
return None

def extract_metadata_from_sdist(filepath: Path) -> Optional[Tuple[str, str, str]]:
"get metadata from a tar.gz or .zip package"
open_func = tarfile.open if filepath.suffixes[-2:] == ['.tar', '.gz'] else zipfile.ZipFile
sdist_name = filepath.name
try:
name, version = parse_sdist_filename(sdist_name)
filename_name = canonicalize_name(name)
filename_version = str(version)
except Exception as e:
print(f"❌ Could not parse filename: {sdist_name}", e)
return None

with open_func(filepath, 'r') as archive:
namelist = archive.getnames() if isinstance(archive, tarfile.TarFile) else archive.namelist()
for name in namelist:
if name.endswith('PKG-INFO'):
content = archive.extractfile(name).read() if isinstance(archive, tarfile.TarFile) else archive.open(name).read()
metadata = message_from_bytes(content)
name = canonicalize_name(str(metadata.get('Name', 'unknown'))) # Avoid Head type
version = str(metadata.get('Version', 'unknown'))
summary = utils.sum_up(str(metadata.get('Summary', '')))
return name, version, summary
if isinstance(archive, tarfile.TarFile):
content = archive.extractfile(name)
else:
content = archive.open(name)
if content:
metadata = BytesParser(policy=default).parse(content)
meta_name = canonicalize_name(str(metadata.get('Name', 'unknown'))) # Avoid Head type
meta_version = str(metadata.get('Version', 'unknown'))
summary = utils.sum_up(str(metadata.get('Summary', '')))
# Assert consistency
if meta_name != filename_name or meta_version != filename_version:
print(f"⚠️ Mismatch in {sdist_name}: filename says {filename_name}=={filename_version}, "
f"but METADATA says {meta_name}=={meta_version}")
return None
return meta_name, meta_version, summary
return None

def list_packages_with_metadata(directory: str) -> List[Tuple[str, str, str]]:
Expand Down
4 changes: 2 additions & 2 deletions winpython/wppm.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@
import json
from pathlib import Path
from argparse import ArgumentParser, RawTextHelpFormatter
from winpython import utils, piptree, associate
from winpython import wheelhouse as wh
from . import utils, piptree, associate
from . import wheelhouse as wh
from operator import itemgetter
# Workaround for installing PyVISA on Windows from source:
os.environ["HOME"] = os.environ["USERPROFILE"]
Expand Down