Skip to content
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
14 changes: 6 additions & 8 deletions micropip/_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ def best_compatible_tag_index(tags: frozenset[Tag]) -> int | None:
return None


def is_package_compatible(filename: str) -> bool:
def is_package_compatible(filename: str) -> tuple[bool, int | None]:
"""
Check if a package is compatible with the current platform.

Expand All @@ -128,25 +128,23 @@ def is_package_compatible(filename: str) -> bool:
"""

if not filename.endswith(".whl"):
return False

if filename.endswith("py3-none-any.whl"):
return True
return False, None

try:
tags = parse_tags(filename)
except (InvalidVersion, InvalidWheelFilename):
return False
return False, None

return best_compatible_tag_index(tags) is not None
tag_index = best_compatible_tag_index(tags)
return (tag_index is not None), tag_index


def check_compatible(filename: str) -> None:
"""
Check if a package is compatible with the current platform.
If not, raise an exception with a error message that explains why.
"""
compatible = is_package_compatible(filename)
compatible, _ = is_package_compatible(filename)
if compatible:
return

Expand Down
3 changes: 2 additions & 1 deletion micropip/package_index.py
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ def _compatible_wheels(

# Checking compatibility takes a bit of time,
# so we use a generator to avoid doing it for all files.
compatible = is_package_compatible(filename)
compatible, tag_index = is_package_compatible(filename)
if not compatible:
continue

Expand Down Expand Up @@ -177,6 +177,7 @@ def _compatible_wheels(
size=size,
core_metadata=core_metadata,
yanked_reason=yanked_reason,
best_tag_index=tag_index,
)

@classmethod
Expand Down
3 changes: 1 addition & 2 deletions micropip/transaction.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
from . import package_index
from ._compat import CompatibilityLayer
from ._utils import (
best_compatible_tag_index,
check_compatible,
constrain_requirement,
validate_constraints,
Expand Down Expand Up @@ -413,7 +412,7 @@ def _find_best_wheel(wheels: Iterable[WheelInfo]) -> WheelInfo | None:
best_wheel = None
best_tag_index = float("infinity")
for wheel in wheels:
tag_index = best_compatible_tag_index(wheel.tags)
tag_index = wheel.best_tag_index
if tag_index is not None and tag_index < best_tag_index:
best_wheel = wheel
best_tag_index = tag_index
Expand Down
14 changes: 13 additions & 1 deletion micropip/wheelinfo.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
loadedPackages,
to_js,
)
from ._utils import parse_wheel_filename
from ._utils import best_compatible_tag_index, parse_wheel_filename
from ._vendored.packaging.src.packaging.requirements import Requirement
from ._vendored.packaging.src.packaging.tags import Tag
from ._vendored.packaging.src.packaging.version import Version
Expand Down Expand Up @@ -47,6 +47,7 @@ class WheelInfo:
yanked_reason: str | bool = (
False # Whether the wheel has been yanked and the reason (if given) (PEP-592)
)
_best_tag_index: int | None = field(default=None, repr=False, compare=False)

# Fields below are only available after downloading the wheel, i.e. after calling `download()`.

Expand All @@ -62,6 +63,15 @@ def __post_init__(self):
self.metadata_url = self.url + ".metadata"
self.yanked = bool(self.yanked_reason)

@property
def best_tag_index(self) -> int | None:
"""
Returns an index if a compatible tag exists, otherwise None.
"""
if self._best_tag_index is None:
self._best_tag_index = best_compatible_tag_index(self.tags)
return self._best_tag_index

@classmethod
def from_url(cls, url: str) -> "WheelInfo":
"""Parse wheels URL and extract available metadata
Expand Down Expand Up @@ -101,6 +111,7 @@ def from_package_index(
size: int | None,
core_metadata: DistributionMetadata = None,
yanked_reason: str | bool = False,
best_tag_index: int | None = None,
) -> "WheelInfo":
"""Extract available metadata from response received from package index"""
parsed_url = urlparse(url)
Expand All @@ -118,6 +129,7 @@ def from_package_index(
size=size,
core_metadata=core_metadata,
yanked_reason=yanked_reason,
_best_tag_index=best_tag_index,
)

async def install(self, target: Path) -> None:
Expand Down