diff --git a/news/9186.feature.rst b/news/9186.feature.rst new file mode 100644 index 00000000000..175b5a883ac --- /dev/null +++ b/news/9186.feature.rst @@ -0,0 +1,3 @@ +New resolver: Error message shown when a wheel contains inconsistent metadata +is made more helpful by including both values from the file name and internal +metadata. diff --git a/src/pip/_internal/exceptions.py b/src/pip/_internal/exceptions.py index 43d083205a0..891f8c37654 100644 --- a/src/pip/_internal/exceptions.py +++ b/src/pip/_internal/exceptions.py @@ -7,7 +7,7 @@ if MYPY_CHECK_RUNNING: import configparser from hashlib import _Hash - from typing import Any, Dict, List, Optional + from typing import Dict, List, Optional from pip._vendor.pkg_resources import Distribution from pip._vendor.requests.models import Request, Response @@ -123,17 +123,20 @@ class MetadataInconsistent(InstallationError): that do not match the information previously obtained from sdist filename or user-supplied ``#egg=`` value. """ - def __init__(self, ireq, field, built): - # type: (InstallRequirement, str, Any) -> None + def __init__(self, ireq, field, f_val, m_val): + # type: (InstallRequirement, str, str, str) -> None self.ireq = ireq self.field = field - self.built = built + self.f_val = f_val + self.m_val = m_val def __str__(self): # type: () -> str - return "Requested {} has different {} in metadata: {!r}".format( - self.ireq, self.field, self.built, + template = ( + "Requested {} has inconsistent {}: " + "filename has {!r}, but metadata has {!r}" ) + return template.format(self.ireq, self.field, self.f_val, self.m_val) class InstallationSubprocessError(InstallationError): diff --git a/src/pip/_internal/resolution/resolvelib/candidates.py b/src/pip/_internal/resolution/resolvelib/candidates.py index 6725684a515..91662b326b7 100644 --- a/src/pip/_internal/resolution/resolvelib/candidates.py +++ b/src/pip/_internal/resolution/resolvelib/candidates.py @@ -204,12 +204,21 @@ def _prepare_distribution(self): def _check_metadata_consistency(self, dist): # type: (Distribution) -> None """Check for consistency of project name and version of dist.""" - name = canonicalize_name(dist.project_name) - if self._name is not None and self._name != name: - raise MetadataInconsistent(self._ireq, "name", dist.project_name) - version = dist.parsed_version - if self._version is not None and self._version != version: - raise MetadataInconsistent(self._ireq, "version", dist.version) + canonical_name = canonicalize_name(dist.project_name) + if self._name is not None and self._name != canonical_name: + raise MetadataInconsistent( + self._ireq, + "name", + self._name, + dist.project_name, + ) + if self._version is not None and self._version != dist.parsed_version: + raise MetadataInconsistent( + self._ireq, + "version", + str(self._version), + dist.version, + ) def _prepare(self): # type: () -> Distribution diff --git a/tests/functional/test_install.py b/tests/functional/test_install.py index 9c36fef0ecb..1c0650c6f5f 100644 --- a/tests/functional/test_install.py +++ b/tests/functional/test_install.py @@ -1455,7 +1455,7 @@ def test_install_editable_with_wrong_egg_name(script, resolver_variant): "for project name pkga. Fix your #egg=pkgb " "fragments.") in result.stderr if resolver_variant == "2020-resolver": - assert "has different name in metadata" in result.stderr, str(result) + assert "has inconsistent" in result.stderr, str(result) else: assert "Successfully installed pkga" in str(result), str(result) diff --git a/tests/functional/test_new_resolver.py b/tests/functional/test_new_resolver.py index f3850c208c6..95422d22627 100644 --- a/tests/functional/test_new_resolver.py +++ b/tests/functional/test_new_resolver.py @@ -1233,7 +1233,9 @@ def test_new_resolver_skip_inconsistent_metadata(script): allow_stderr_warning=True, ) - assert " different version in metadata: '2'" in result.stderr, str(result) + assert ( + " inconsistent version: filename has '3', but metadata has '2'" + ) in result.stderr, str(result) assert_installed(script, a="1")