提交 09d31159 编写于 作者: P Paul Moore

Move error handling to factory.get_installation_error()

上级 c827f296
...@@ -5,6 +5,7 @@ from pip._vendor import six ...@@ -5,6 +5,7 @@ from pip._vendor import six
from pip._vendor.packaging.utils import canonicalize_name from pip._vendor.packaging.utils import canonicalize_name
from pip._internal.exceptions import ( from pip._internal.exceptions import (
DistributionNotFound,
InstallationError, InstallationError,
UnsupportedPythonVersion, UnsupportedPythonVersion,
) )
...@@ -343,11 +344,79 @@ class Factory(object): ...@@ -343,11 +344,79 @@ class Factory(object):
return UnsupportedPythonVersion(message) return UnsupportedPythonVersion(message)
def get_installation_error(self, e): def get_installation_error(self, e):
# type: (ResolutionImpossible) -> Optional[InstallationError] # type: (ResolutionImpossible) -> InstallationError
assert e.causes, "Installation error reported with no cause"
# If one of the things we can't solve is "we need Python X.Y",
# that is what we report.
for cause in e.causes: for cause in e.causes:
if isinstance(cause.requirement, RequiresPythonRequirement): if isinstance(cause.requirement, RequiresPythonRequirement):
return self._report_requires_python_error( return self._report_requires_python_error(
cause.requirement, cause.requirement,
cause.parent, cause.parent,
) )
return None
# Otherwise, we have a set of causes which can't all be satisfied
# at once.
# The simplest case is when we have *one* cause that can't be
# satisfied. We just report that case.
if len(e.causes) == 1:
req, parent = e.causes[0]
logger.critical(
"Could not find a version that satisfies " +
"the requirement " +
str(req) +
("" if parent is None else " (from {})".format(
parent.name
))
)
return DistributionNotFound(
'No matching distribution found for {}'.format(req)
)
# OK, we now have a list of requirements that can't all be
# satisfied at once.
# A couple of formatting helpers
def text_join(parts):
# type: (List[str]) -> str
if len(parts) == 1:
return parts[0]
return ", ".join(parts[:-1]) + " and " + parts[-1]
def readable_form(cand):
# type: (Candidate) -> str
return "{} {}".format(cand.name, cand.version)
msg = "Cannot install {} because these package versions " \
"have conflicting dependencies.".format(
text_join([
readable_form(parent)
for req, parent in e.causes
if parent
])
)
msg = msg + "\nThe conflict is caused by:"
for req, parent in e.causes:
msg = msg + "\n "
if parent:
msg = msg + readable_form(parent) + " depends on "
else:
msg = msg + "The user requested "
msg = msg + str(req)
msg = msg + "\n\n" + \
"There are a number of possible solutions. " + \
"For instructions on how to do these steps visit: " + \
"https://pypa.io/SomeLink"
logger.critical(msg)
return DistributionNotFound(
"No matching distribution found for " +
", ".join(sorted(set(r.name for r, _ in e.causes)))
)
...@@ -6,7 +6,7 @@ from pip._vendor.packaging.utils import canonicalize_name ...@@ -6,7 +6,7 @@ from pip._vendor.packaging.utils import canonicalize_name
from pip._vendor.resolvelib import BaseReporter, ResolutionImpossible from pip._vendor.resolvelib import BaseReporter, ResolutionImpossible
from pip._vendor.resolvelib import Resolver as RLResolver from pip._vendor.resolvelib import Resolver as RLResolver
from pip._internal.exceptions import DistributionNotFound, InstallationError from pip._internal.exceptions import InstallationError
from pip._internal.req.req_set import RequirementSet from pip._internal.req.req_set import RequirementSet
from pip._internal.resolution.base import BaseResolver from pip._internal.resolution.base import BaseResolver
from pip._internal.resolution.resolvelib.provider import PipProvider from pip._internal.resolution.resolvelib.provider import PipProvider
...@@ -142,53 +142,6 @@ class Resolver(BaseResolver): ...@@ -142,53 +142,6 @@ class Resolver(BaseResolver):
except ResolutionImpossible as e: except ResolutionImpossible as e:
error = self.factory.get_installation_error(e) error = self.factory.get_installation_error(e)
if not error:
# > pip install ward==0.44.1b0 py2neo==4.3.0 --unstable-feature=resolver
#
# ERROR: Cannot install ward v0.44.1b0 and py2neo v4.3.0 because these package versions have conflicting dependencies.
# The conflict is caused by:
# ward 0.44.1b0 depends on pygments <3.0.0,>=2.4.2
# py2neo 4.3.0 depends on pygments ~=2.3.1
#
# There are a number of possible solutions. For instructions on how to do these steps visit: https://pypa.io/SomeLink
def text_join(parts):
# type: (List[str]) -> str
return ", ".join(parts[:-1]) + " and " + parts[-1]
def readable_form(req):
# type: (InstallRequirement) -> str
return "{} {}".format(req.name, req.version)
# TODO: I haven't considered what happens if `parent` is None.
# I'm not even sure how that case arises...
logger.critical(
"Cannot install " +
text_join([
readable_form(parent)
for req, parent in e.causes
if parent
]) +
" because these package versions" +
" have conflicting dependencies."
)
logger.info("The conflict is caused by: ")
for req, parent in e.causes:
logger.info(
" " +
readable_form(parent) +
" depends on " +
str(req)
)
logger.info(
"There are a number of possible solutions. " +
"For instructions on how to do these steps visit: " +
"https://pypa.io/SomeLink"
)
raise DistributionNotFound(
"No matching distribution found for " +
", ".join(sorted(set(r.name for r, _ in e.causes)))
)
six.raise_from(error, e) six.raise_from(error, e)
req_set = RequirementSet(check_supported_wheels=check_supported_wheels) req_set = RequirementSet(check_supported_wheels=check_supported_wheels)
......
...@@ -282,9 +282,7 @@ def test_new_resolver_no_dist_message(script): ...@@ -282,9 +282,7 @@ def test_new_resolver_no_dist_message(script):
assert "Could not find a version that satisfies the requirement B" \ assert "Could not find a version that satisfies the requirement B" \
in result.stderr, str(result) in result.stderr, str(result)
# TODO: This reports the canonical name of the project. But the current assert "No matching distribution found for B" in result.stderr, str(result)
# 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): def test_new_resolver_installs_editable(script):
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册