diff --git a/src/pip/_internal/resolution/resolvelib/requirements.py b/src/pip/_internal/resolution/resolvelib/requirements.py index a7f0ec31388..8682b2f7ede 100644 --- a/src/pip/_internal/resolution/resolvelib/requirements.py +++ b/src/pip/_internal/resolution/resolvelib/requirements.py @@ -50,6 +50,10 @@ def __init__(self, ireq, factory): self._factory = factory self.extras = ireq.req.extras + def __str__(self): + # type: () -> str + return str(self._ireq.req) + def __repr__(self): # type: () -> str return "{class_name}({requirement!r})".format( diff --git a/src/pip/_internal/resolution/resolvelib/resolver.py b/src/pip/_internal/resolution/resolvelib/resolver.py index ade0b5d86ed..cba5a496508 100644 --- a/src/pip/_internal/resolution/resolvelib/resolver.py +++ b/src/pip/_internal/resolution/resolvelib/resolver.py @@ -1,4 +1,5 @@ import functools +import logging from pip._vendor import six from pip._vendor.packaging.utils import canonicalize_name @@ -25,6 +26,9 @@ from pip._internal.resolution.base import InstallRequirementProvider +logger = logging.getLogger(__name__) + + class Resolver(BaseResolver): def __init__( self, @@ -74,9 +78,27 @@ def resolve(self, root_reqs, check_supported_wheels): try: self._result = resolver.resolve(requirements) + except ResolutionImpossible as e: error = self.factory.get_installation_error(e) if not error: + # TODO: This needs fixing, we need to look at the + # factory.get_installation_error infrastructure, as that + # doesn't really allow for the logger.critical calls I'm + # using here. + for req, parent in e.causes: + logger.critical( + "Could not find a version that satisfies " + + "the requirement " + + str(req) + + ("" if parent is None else " (from {})".format( + parent.name + )) + ) + raise InstallationError( + "No matching distribution found for " + + ", ".join([r.name for r, _ in e.causes]) + ) raise six.raise_from(error, e) diff --git a/tests/functional/test_new_resolver.py b/tests/functional/test_new_resolver.py index 6b984704deb..cb384d7a0ac 100644 --- a/tests/functional/test_new_resolver.py +++ b/tests/functional/test_new_resolver.py @@ -156,6 +156,41 @@ def test_new_resolver_installs_extras(script): assert_installed(script, base="0.1.0", dep="0.1.0") +def test_new_resolver_installed_message(script): + create_basic_wheel_for_package(script, "A", "1.0") + result = script.pip( + "install", "--unstable-feature=resolver", + "--no-cache-dir", "--no-index", + "--find-links", script.scratch_path, + "A", + expect_stderr=False, + ) + assert "Successfully installed A-1.0" in result.stdout, str(result) + + +def test_new_resolver_no_dist_message(script): + create_basic_wheel_for_package(script, "A", "1.0") + result = script.pip( + "install", "--unstable-feature=resolver", + "--no-cache-dir", "--no-index", + "--find-links", script.scratch_path, + "B", + expect_error=True, + expect_stderr=True, + ) + + # Full messages from old resolver: + # ERROR: Could not find a version that satisfies the + # requirement xxx (from versions: none) + # ERROR: No matching distribution found for xxx + + assert "Could not find a version that satisfies the requirement B" \ + in result.stderr, str(result) + # TODO: This reports the canonical name of the project. But the current + # resolver reports the originally specified name (i.e. uppercase B) + assert "No matching distribution found for b" in result.stderr, str(result) + + def test_new_resolver_installs_editable(script): create_basic_wheel_for_package( script,