Simplify CandidateEvaluator.evaluate_link().

This commit is contained in:
Chris Jerdonek 2019-05-08 20:07:39 -04:00
parent 6217335a41
commit c54e50f50b
2 changed files with 45 additions and 39 deletions

View File

@ -290,12 +290,15 @@ class CandidateEvaluator(object):
# type: (Wheel) -> bool # type: (Wheel) -> bool
return wheel.supported(self._valid_tags) return wheel.supported(self._valid_tags)
def evaluate_link(self, link, search): def _evaluate_link(self, link, search):
# type: (Link, Search) -> Optional[InstallationCandidate] # type: (Link, Search) -> Tuple[bool, Optional[str]]
""" """
Determine whether a link is a candidate for installation. Determine whether a link is a candidate for installation.
Returns an InstallationCandidate if so, otherwise None. :return: A tuple (is_candidate, result), where `result` is (1) a
version string if `is_candidate` is True, and (2) if
`is_candidate` is False, an optional string to log the reason
the link fails to qualify.
""" """
version = None version = None
if link.egg_fragment: if link.egg_fragment:
@ -304,61 +307,43 @@ class CandidateEvaluator(object):
else: else:
egg_info, ext = link.splitext() egg_info, ext = link.splitext()
if not ext: if not ext:
self._log_skipped_link(link, 'not a file') return (False, 'not a file')
return None
if ext not in SUPPORTED_EXTENSIONS: if ext not in SUPPORTED_EXTENSIONS:
self._log_skipped_link( return (False, 'unsupported archive format: %s' % ext)
link, 'unsupported archive format: %s' % ext,
)
return None
if "binary" not in search.formats and ext == WHEEL_EXTENSION: if "binary" not in search.formats and ext == WHEEL_EXTENSION:
self._log_skipped_link( reason = 'No binaries permitted for %s' % search.supplied
link, 'No binaries permitted for %s' % search.supplied, return (False, reason)
)
return None
if "macosx10" in link.path and ext == '.zip': if "macosx10" in link.path and ext == '.zip':
self._log_skipped_link(link, 'macosx10 one') return (False, 'macosx10 one')
return None
if ext == WHEEL_EXTENSION: if ext == WHEEL_EXTENSION:
try: try:
wheel = Wheel(link.filename) wheel = Wheel(link.filename)
except InvalidWheelFilename: except InvalidWheelFilename:
self._log_skipped_link(link, 'invalid wheel filename') return (False, 'invalid wheel filename')
return None
if canonicalize_name(wheel.name) != search.canonical: if canonicalize_name(wheel.name) != search.canonical:
self._log_skipped_link( reason = 'wrong project name (not %s)' % search.supplied
link, 'wrong project name (not %s)' % search.supplied) return (False, reason)
return None
if not self._is_wheel_supported(wheel): if not self._is_wheel_supported(wheel):
self._log_skipped_link( return (False, 'it is not compatible with this Python')
link, 'it is not compatible with this Python')
return None
version = wheel.version version = wheel.version
# This should be up by the search.ok_binary check, but see issue 2700. # This should be up by the search.ok_binary check, but see issue 2700.
if "source" not in search.formats and ext != WHEEL_EXTENSION: if "source" not in search.formats and ext != WHEEL_EXTENSION:
self._log_skipped_link( return (False, 'No sources permitted for %s' % search.supplied)
link, 'No sources permitted for %s' % search.supplied,
)
return None
if not version: if not version:
version = _egg_info_matches(egg_info, search.canonical) version = _egg_info_matches(egg_info, search.canonical)
if not version: if not version:
self._log_skipped_link( return (False, 'Missing project version for %s' % search.supplied)
link, 'Missing project version for %s' % search.supplied)
return None
match = self._py_version_re.search(version) match = self._py_version_re.search(version)
if match: if match:
version = version[:match.start()] version = version[:match.start()]
py_version = match.group(1) py_version = match.group(1)
if py_version != sys.version[:3]: if py_version != sys.version[:3]:
self._log_skipped_link( return (False, 'Python version is incorrect')
link, 'Python version is incorrect')
return None
try: try:
support_this_python = check_requires_python( support_this_python = check_requires_python(
link.requires_python, version_info=sys.version_info[:3], link.requires_python, version_info=sys.version_info[:3],
@ -372,10 +357,29 @@ class CandidateEvaluator(object):
logger.debug("The package %s is incompatible with the python " logger.debug("The package %s is incompatible with the python "
"version in use. Acceptable python versions are: %s", "version in use. Acceptable python versions are: %s",
link, link.requires_python) link, link.requires_python)
return None # Return None for the reason text to suppress calling
# _log_skipped_link().
return (False, None)
logger.debug('Found link %s, version: %s', link, version) logger.debug('Found link %s, version: %s', link, version)
return InstallationCandidate(search.supplied, version, link) return (True, version)
def get_install_candidate(self, link, search):
# type: (Link, Search) -> Optional[InstallationCandidate]
"""
If the link is a candidate for install, convert it to an
InstallationCandidate and return it. Otherwise, return None.
"""
is_candidate, result = self._evaluate_link(link, search=search)
if not is_candidate:
if result:
self._log_skipped_link(link, reason=result)
return None
return InstallationCandidate(
search.supplied, location=link, version=result,
)
def _sort_key(self, candidate): def _sort_key(self, candidate):
# type: (InstallationCandidate) -> CandidateSortingKey # type: (InstallationCandidate) -> CandidateSortingKey
@ -776,7 +780,8 @@ class PackageFinder(object):
This checks index_urls and find_links. This checks index_urls and find_links.
All versions found are returned as an InstallationCandidate list. All versions found are returned as an InstallationCandidate list.
See evaluate_link() for details on which files are accepted See CandidateEvaluator._evaluate_link() for details on which files
are accepted.
""" """
index_locations = self._get_index_urls_locations(project_name) index_locations = self._get_index_urls_locations(project_name)
index_file_loc, index_url_loc = self._sort_locations(index_locations) index_file_loc, index_url_loc = self._sort_locations(index_locations)
@ -976,7 +981,8 @@ class PackageFinder(object):
# type: (...) -> List[InstallationCandidate] # type: (...) -> List[InstallationCandidate]
result = [] result = []
for link in self._sort_links(links): for link in self._sort_links(links):
candidate = self.candidate_evaluator.evaluate_link(link, search) candidate = self.candidate_evaluator.get_install_candidate(
link, search)
if candidate is not None: if candidate is not None:
result.append(candidate) result.append(candidate)
return result return result

View File

@ -489,7 +489,7 @@ class TestCandidateEvaluator(object):
canonical=self.canonical_name, canonical=self.canonical_name,
formats=['source', 'binary'], formats=['source', 'binary'],
) )
result = self.evaluator.evaluate_link(link, search) result = self.evaluator.get_install_candidate(link, search)
expected = InstallationCandidate(self.search_name, self.version, link) expected = InstallationCandidate(self.search_name, self.version, link)
assert result == expected, result assert result == expected, result
@ -510,7 +510,7 @@ class TestCandidateEvaluator(object):
canonical=self.canonical_name, canonical=self.canonical_name,
formats=['source', 'binary'], formats=['source', 'binary'],
) )
result = self.evaluator.evaluate_link(link, search) result = self.evaluator.get_install_candidate(link, search)
assert result is None, result assert result is None, result