Move get_install_candidate() to PackageFinder.

This commit is contained in:
Chris Jerdonek 2019-05-19 10:06:43 -07:00
parent 33959b02d3
commit 7995e2d5a9
2 changed files with 47 additions and 50 deletions

View File

@ -291,20 +291,12 @@ class CandidateEvaluator(object):
# CandidateEvaluator is generally instantiated only once per pip
# invocation (when PackageFinder is instantiated).
self._py_version_re = re.compile(r'-py([123]\.?[0-9]?)$')
# These are boring links that have already been logged somehow.
self._logged_links = set() # type: Set[Link]
def _log_skipped_link(self, link, reason):
# type: (Link, str) -> None
if link not in self._logged_links:
logger.debug('Skipping link %s; %s', link, reason)
self._logged_links.add(link)
def _is_wheel_supported(self, wheel):
# type: (Wheel) -> bool
return wheel.supported(self._valid_tags)
def _evaluate_link(self, link, search):
def evaluate_link(self, link, search):
# type: (Link, Search) -> Tuple[bool, Optional[str]]
"""
Determine whether a link is a candidate for installation.
@ -380,22 +372,6 @@ class CandidateEvaluator(object):
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):
# type: (InstallationCandidate) -> CandidateSortingKey
"""
@ -558,6 +534,9 @@ class PackageFinder(object):
self.allow_all_prereleases = allow_all_prereleases
self.format_control = format_control
# These are boring links that have already been logged somehow.
self._logged_links = set() # type: Set[Link]
@classmethod
def create(
cls,
@ -830,7 +809,7 @@ class PackageFinder(object):
This checks index_urls and find_links.
All versions found are returned as an InstallationCandidate list.
See CandidateEvaluator._evaluate_link() for details on which files
See CandidateEvaluator.evaluate_link() for details on which files
are accepted.
"""
index_locations = self._get_index_urls_locations(project_name)
@ -1023,6 +1002,30 @@ class PackageFinder(object):
no_eggs.append(link)
return no_eggs + eggs
def _log_skipped_link(self, link, reason):
# type: (Link, str) -> None
if link not in self._logged_links:
logger.debug('Skipping link %s; %s', link, reason)
self._logged_links.add(link)
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.candidate_evaluator.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 _package_versions(
self,
links, # type: Iterable[Link]

View File

@ -470,20 +470,16 @@ class TestCandidateEvaluator(object):
lambda x: Distribution(project_name='setuptools', version='0.9')
)
def setup(self):
self.version = '1.0'
self.search_name = 'pytest'
self.canonical_name = 'pytest'
valid_tags = pip._internal.pep425tags.get_supported()
self.evaluator = CandidateEvaluator(valid_tags=valid_tags)
@pytest.mark.parametrize(
'url',
[
'http:/yo/pytest-1.0.tar.gz',
'http:/yo/pytest-1.0-py2.py3-none-any.whl',
],
)
def test_evaluate_link__match(self, url):
@pytest.mark.parametrize('url, expected_version', [
('http:/yo/pytest-1.0.tar.gz', '1.0'),
('http:/yo/pytest-1.0-py2.py3-none-any.whl', '1.0'),
])
def test_evaluate_link__match(self, url, expected_version):
"""Test that 'pytest' archives match for 'pytest'"""
link = Link(url)
search = Search(
@ -491,20 +487,18 @@ class TestCandidateEvaluator(object):
canonical=self.canonical_name,
formats=['source', 'binary'],
)
result = self.evaluator.get_install_candidate(link, search)
expected = InstallationCandidate(self.search_name, self.version, link)
assert result == expected, result
actual = self.evaluator.evaluate_link(link, search)
assert actual == (True, expected_version)
@pytest.mark.parametrize(
'url',
[
# TODO: Uncomment this test case when #1217 is fixed.
# 'http:/yo/pytest-xdist-1.0.tar.gz',
'http:/yo/pytest2-1.0.tar.gz',
'http:/yo/pytest_xdist-1.0-py2.py3-none-any.whl',
],
)
def test_evaluate_link__substring_fails(self, url):
@pytest.mark.parametrize('url, expected_msg', [
# TODO: Uncomment this test case when #1217 is fixed.
# 'http:/yo/pytest-xdist-1.0.tar.gz',
('http:/yo/pytest2-1.0.tar.gz',
'Missing project version for pytest'),
('http:/yo/pytest_xdist-1.0-py2.py3-none-any.whl',
'wrong project name (not pytest)'),
])
def test_evaluate_link__substring_fails(self, url, expected_msg):
"""Test that 'pytest<something> archives won't match for 'pytest'."""
link = Link(url)
search = Search(
@ -512,8 +506,8 @@ class TestCandidateEvaluator(object):
canonical=self.canonical_name,
formats=['source', 'binary'],
)
result = self.evaluator.get_install_candidate(link, search)
assert result is None, result
actual = self.evaluator.evaluate_link(link, search)
assert actual == (False, expected_msg)
def test_get_index_urls_locations():