From 63639bfc0f6daa5cf18580db71d44e37d2a3b682 Mon Sep 17 00:00:00 2001 From: Chris Jerdonek Date: Fri, 9 Aug 2019 23:19:19 -0700 Subject: [PATCH] Make tags required in Wheel.support_index_min() and supported(). --- src/pip/_internal/cache.py | 51 +++++++++++++++++++++------- src/pip/_internal/req/req_install.py | 9 +++-- src/pip/_internal/req/req_set.py | 4 ++- src/pip/_internal/wheel.py | 21 +++++++----- 4 files changed, 61 insertions(+), 24 deletions(-) diff --git a/src/pip/_internal/cache.py b/src/pip/_internal/cache.py index 0e893cd45..433b27bb9 100644 --- a/src/pip/_internal/cache.py +++ b/src/pip/_internal/cache.py @@ -21,6 +21,7 @@ from pip._internal.wheel import InvalidWheelFilename, Wheel if MYPY_CHECK_RUNNING: from typing import Optional, Set, List, Any from pip._internal.index import FormatControl + from pip._internal.pep425tags import Pep425Tag logger = logging.getLogger(__name__) @@ -103,8 +104,13 @@ class Cache(object): """ raise NotImplementedError() - def get(self, link, package_name): - # type: (Link, Optional[str]) -> Link + def get( + self, + link, # type: Link + package_name, # type: Optional[str] + supported_tags, # type: List[Pep425Tag] + ): + # type: (...) -> Link """Returns a link to a cached item if it exists, otherwise returns the passed link. """ @@ -153,8 +159,13 @@ class SimpleWheelCache(Cache): # Store wheels within the root cache_dir return os.path.join(self.cache_dir, "wheels", *parts) - def get(self, link, package_name): - # type: (Link, Optional[str]) -> Link + def get( + self, + link, # type: Link + package_name, # type: Optional[str] + supported_tags, # type: List[Pep425Tag] + ): + # type: (...) -> Link candidates = [] for wheel_name in self._get_candidates(link, package_name): @@ -162,10 +173,12 @@ class SimpleWheelCache(Cache): wheel = Wheel(wheel_name) except InvalidWheelFilename: continue - if not wheel.supported(): + if not wheel.supported(supported_tags): # Built for a different python/arch/etc continue - candidates.append((wheel.support_index_min(), wheel_name)) + candidates.append( + (wheel.support_index_min(supported_tags), wheel_name) + ) if not candidates: return link @@ -214,12 +227,26 @@ class WheelCache(Cache): # type: (Link) -> str return self._ephem_cache.get_path_for_link(link) - def get(self, link, package_name): - # type: (Link, Optional[str]) -> Link - retval = self._wheel_cache.get(link, package_name) - if retval is link: - retval = self._ephem_cache.get(link, package_name) - return retval + def get( + self, + link, # type: Link + package_name, # type: Optional[str] + supported_tags, # type: List[Pep425Tag] + ): + # type: (...) -> Link + retval = self._wheel_cache.get( + link=link, + package_name=package_name, + supported_tags=supported_tags, + ) + if retval is not link: + return retval + + return self._ephem_cache.get( + link=link, + package_name=package_name, + supported_tags=supported_tags, + ) def cleanup(self): # type: () -> None diff --git a/src/pip/_internal/req/req_install.py b/src/pip/_internal/req/req_install.py index 4752fa888..d57804da1 100644 --- a/src/pip/_internal/req/req_install.py +++ b/src/pip/_internal/req/req_install.py @@ -18,7 +18,7 @@ from pip._vendor.packaging.version import Version from pip._vendor.packaging.version import parse as parse_version from pip._vendor.pep517.wrappers import Pep517HookCaller -from pip._internal import wheel +from pip._internal import pep425tags, wheel from pip._internal.build_env import NoOpBuildEnvironment from pip._internal.exceptions import InstallationError from pip._internal.models.link import Link @@ -222,7 +222,12 @@ class InstallRequirement(object): self.link = finder.find_requirement(self, upgrade) if self._wheel_cache is not None and not require_hashes: old_link = self.link - self.link = self._wheel_cache.get(self.link, self.name) + supported_tags = pep425tags.get_supported() + self.link = self._wheel_cache.get( + link=self.link, + package_name=self.name, + supported_tags=supported_tags, + ) if old_link != self.link: logger.debug('Using cached wheel link: %s', self.link) diff --git a/src/pip/_internal/req/req_set.py b/src/pip/_internal/req/req_set.py index 0b81ed215..cd51d1725 100644 --- a/src/pip/_internal/req/req_set.py +++ b/src/pip/_internal/req/req_set.py @@ -6,6 +6,7 @@ from __future__ import absolute_import import logging from collections import OrderedDict +from pip._internal import pep425tags from pip._internal.exceptions import InstallationError from pip._internal.utils.logging import indent_log from pip._internal.utils.typing import MYPY_CHECK_RUNNING @@ -88,7 +89,8 @@ class RequirementSet(object): # single requirements file. if install_req.link and install_req.link.is_wheel: wheel = Wheel(install_req.link.filename) - if self.check_supported_wheels and not wheel.supported(): + tags = pep425tags.get_supported() + if (self.check_supported_wheels and not wheel.supported(tags)): raise InstallationError( "%s is not a supported wheel on this platform." % wheel.filename diff --git a/src/pip/_internal/wheel.py b/src/pip/_internal/wheel.py index d864ffb60..47416735c 100644 --- a/src/pip/_internal/wheel.py +++ b/src/pip/_internal/wheel.py @@ -736,8 +736,8 @@ class Wheel(object): """ return sorted(format_tag(tag) for tag in self.file_tags) - def support_index_min(self, tags=None): - # type: (Optional[List[Pep425Tag]]) -> int + def support_index_min(self, tags): + # type: (List[Pep425Tag]) -> int """ Return the lowest index that one of the wheel's file_tag combinations achieves in the given list of supported tags. @@ -745,18 +745,21 @@ class Wheel(object): For example, if there are 8 supported tags and one of the file tags is first in the list, then return 0. + :param tags: the PEP 425 tags to check the wheel against, in order + with most preferred first. + :raises ValueError: If none of the wheel's file tags match one of the supported tags. """ - if tags is None: # for mock - tags = pep425tags.get_supported() return min(tags.index(tag) for tag in self.file_tags if tag in tags) - def supported(self, tags=None): - # type: (Optional[List[Pep425Tag]]) -> bool - """Return whether this wheel is supported by one of the given tags.""" - if tags is None: # for mock - tags = pep425tags.get_supported() + def supported(self, tags): + # type: (List[Pep425Tag]) -> bool + """ + Return whether the wheel is compatible with one of the given tags. + + :param tags: the PEP 425 tags to check the wheel against. + """ return not self.file_tags.isdisjoint(tags)