mirror of
https://github.com/pypa/pip
synced 2023-12-13 21:30:23 +01:00
Improve the debug log message when installing an incompatible wheel.
This commit is contained in:
parent
c197b11816
commit
a9a9cfd98c
2
news/6121.feature
Normal file
2
news/6121.feature
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
Include the wheel's tags in the log message explanation when a candidate
|
||||||
|
wheel link is found incompatible.
|
|
@ -384,7 +384,15 @@ class CandidateEvaluator(object):
|
||||||
return (False, reason)
|
return (False, reason)
|
||||||
|
|
||||||
if not self._is_wheel_supported(wheel):
|
if not self._is_wheel_supported(wheel):
|
||||||
return (False, 'it is not compatible with this Python')
|
# Include the wheel's tags in the reason string to
|
||||||
|
# simplify troubleshooting compatibility issues.
|
||||||
|
file_tags = wheel.get_formatted_file_tags()
|
||||||
|
reason = (
|
||||||
|
"none of the wheel's tags match: {}".format(
|
||||||
|
', '.join(file_tags)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
return (False, reason)
|
||||||
|
|
||||||
version = wheel.version
|
version = wheel.version
|
||||||
|
|
||||||
|
@ -1066,7 +1074,9 @@ class PackageFinder(object):
|
||||||
def _log_skipped_link(self, link, reason):
|
def _log_skipped_link(self, link, reason):
|
||||||
# type: (Link, str) -> None
|
# type: (Link, str) -> None
|
||||||
if link not in self._logged_links:
|
if link not in self._logged_links:
|
||||||
logger.debug('Skipping link %s; %s', link, reason)
|
# Put the link at the end so the reason is more visible and
|
||||||
|
# because the link string is usually very long.
|
||||||
|
logger.debug('Skipping link: %s: %s', reason, link)
|
||||||
self._logged_links.add(link)
|
self._logged_links.add(link)
|
||||||
|
|
||||||
def get_install_candidate(self, link, search):
|
def get_install_candidate(self, link, search):
|
||||||
|
|
|
@ -663,6 +663,16 @@ def check_compatibility(version, name):
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def format_tag(file_tag):
|
||||||
|
# type: (Tuple[str, ...]) -> str
|
||||||
|
"""
|
||||||
|
Format three tags in the form "<python_tag>-<abi_tag>-<platform_tag>".
|
||||||
|
|
||||||
|
:param file_tag: A 3-tuple of tags (python_tag, abi_tag, platform_tag).
|
||||||
|
"""
|
||||||
|
return '-'.join(file_tag)
|
||||||
|
|
||||||
|
|
||||||
class Wheel(object):
|
class Wheel(object):
|
||||||
"""A wheel file"""
|
"""A wheel file"""
|
||||||
|
|
||||||
|
@ -702,6 +712,13 @@ class Wheel(object):
|
||||||
for y in self.abis for z in self.plats
|
for y in self.abis for z in self.plats
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def get_formatted_file_tags(self):
|
||||||
|
# type: () -> List[str]
|
||||||
|
"""
|
||||||
|
Return the wheel's tags as a sorted list of strings.
|
||||||
|
"""
|
||||||
|
return sorted(format_tag(tag) for tag in self.file_tags)
|
||||||
|
|
||||||
def support_index_min(self, tags=None):
|
def support_index_min(self, tags=None):
|
||||||
# type: (Optional[List[Pep425Tag]]) -> Optional[int]
|
# type: (Optional[List[Pep425Tag]]) -> Optional[int]
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -105,7 +105,10 @@ def test_command_line_append_flags(script, virtualenv, data):
|
||||||
"Analyzing links from page https://test.pypi.org"
|
"Analyzing links from page https://test.pypi.org"
|
||||||
in result.stdout
|
in result.stdout
|
||||||
)
|
)
|
||||||
assert "Skipping link %s" % data.find_links in result.stdout
|
assert (
|
||||||
|
'Skipping link: not a file: {}'.format(data.find_links) in
|
||||||
|
result.stdout
|
||||||
|
), 'stdout: {}'.format(result.stdout)
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.network
|
@pytest.mark.network
|
||||||
|
@ -127,7 +130,10 @@ def test_command_line_appends_correctly(script, data):
|
||||||
"Analyzing links from page https://test.pypi.org"
|
"Analyzing links from page https://test.pypi.org"
|
||||||
in result.stdout
|
in result.stdout
|
||||||
), result.stdout
|
), result.stdout
|
||||||
assert "Skipping link %s" % data.find_links in result.stdout
|
assert (
|
||||||
|
'Skipping link: not a file: {}'.format(data.find_links) in
|
||||||
|
result.stdout
|
||||||
|
), 'stdout: {}'.format(result.stdout)
|
||||||
|
|
||||||
|
|
||||||
def test_config_file_override_stack(script, virtualenv):
|
def test_config_file_override_stack(script, virtualenv):
|
||||||
|
|
|
@ -133,10 +133,7 @@ class TestWheel:
|
||||||
with pytest.raises(DistributionNotFound):
|
with pytest.raises(DistributionNotFound):
|
||||||
finder.find_requirement(req, True)
|
finder.find_requirement(req, True)
|
||||||
|
|
||||||
assert (
|
assert 'Skipping link: invalid wheel filename:' in caplog.text
|
||||||
"invalid.whl; invalid wheel filename"
|
|
||||||
in caplog.text
|
|
||||||
)
|
|
||||||
|
|
||||||
def test_not_find_wheel_not_supported(self, data, monkeypatch):
|
def test_not_find_wheel_not_supported(self, data, monkeypatch):
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -130,6 +130,24 @@ class TestCandidateEvaluator:
|
||||||
actual = evaluator.evaluate_link(link, search=search)
|
actual = evaluator.evaluate_link(link, search=search)
|
||||||
assert actual == expected
|
assert actual == expected
|
||||||
|
|
||||||
|
def test_evaluate_link__incompatible_wheel(self):
|
||||||
|
"""
|
||||||
|
Test an incompatible wheel.
|
||||||
|
"""
|
||||||
|
link = Link('https://example.com/sample-1.0-py2.py3-none-any.whl')
|
||||||
|
search = Search(
|
||||||
|
supplied='sample', canonical='sample', formats=['binary'],
|
||||||
|
)
|
||||||
|
# Pass an empty list for the valid tags to make sure nothing matches.
|
||||||
|
evaluator = CandidateEvaluator(
|
||||||
|
[], py_version_info=(3, 6, 4),
|
||||||
|
)
|
||||||
|
actual = evaluator.evaluate_link(link, search=search)
|
||||||
|
expected = (
|
||||||
|
False, "none of the wheel's tags match: py2-none-any, py3-none-any"
|
||||||
|
)
|
||||||
|
assert actual == expected
|
||||||
|
|
||||||
|
|
||||||
def test_sort_locations_file_expand_dir(data):
|
def test_sort_locations_file_expand_dir(data):
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -68,6 +68,15 @@ def make_test_install_req(base_name=None):
|
||||||
return req
|
return req
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize('file_tag, expected', [
|
||||||
|
(('py27', 'none', 'any'), 'py27-none-any'),
|
||||||
|
(('cp33', 'cp32dmu', 'linux_x86_64'), 'cp33-cp32dmu-linux_x86_64'),
|
||||||
|
])
|
||||||
|
def test_format_tag(file_tag, expected):
|
||||||
|
actual = wheel.format_tag(file_tag)
|
||||||
|
assert actual == expected
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
"base_name, autobuilding, cache_available, expected",
|
"base_name, autobuilding, cache_available, expected",
|
||||||
[
|
[
|
||||||
|
|
Loading…
Reference in a new issue