Skip to content

Commit

Permalink
Show constraint in error message
Browse files Browse the repository at this point in the history
  • Loading branch information
uranusjr committed Dec 15, 2020
1 parent 03d5f56 commit fa97998
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 17 deletions.
42 changes: 29 additions & 13 deletions src/pip/_internal/resolution/resolvelib/factory.py
Original file line number Diff line number Diff line change
Expand Up @@ -403,8 +403,26 @@ def _report_requires_python_error(
)
return UnsupportedPythonVersion(message)

def get_installation_error(self, e):
# type: (ResolutionImpossible) -> InstallationError
def _report_single_requirement_conflict(self, req, parent):
# type: (Requirement, Candidate) -> DistributionNotFound
if parent is None:
req_disp = str(req)
else:
req_disp = '{} (from {})'.format(req, parent.name)
logger.critical(
"Could not find a version that satisfies the "
"requirement %s", req_disp,
)
return DistributionNotFound(
'No matching distribution found for {}'.format(req)
)

def get_installation_error(
self,
e, # type: ResolutionImpossible
constraints, # type: Dict[str, Constraint]
):
# type: (...) -> InstallationError

assert e.causes, "Installation error reported with no cause"

Expand All @@ -424,17 +442,8 @@ def get_installation_error(self, e):
# satisfied. We just report that case.
if len(e.causes) == 1:
req, parent = e.causes[0]
if parent is None:
req_disp = str(req)
else:
req_disp = '{} (from {})'.format(req, parent.name)
logger.critical(
"Could not find a version that satisfies the requirement %s",
req_disp,
)
return DistributionNotFound(
'No matching distribution found for {}'.format(req)
)
if req.name not in constraints:
return self._report_single_requirement_conflict(req, parent)

# OK, we now have a list of requirements that can't all be
# satisfied at once.
Expand Down Expand Up @@ -474,7 +483,11 @@ def describe_trigger(parent):
"have conflicting dependencies.".format(info)
logger.critical(msg)
msg = "\nThe conflict is caused by:"

relevant_constraints = set()
for req, parent in e.causes:
if req.name in constraints:
relevant_constraints.add(req.name)
msg = msg + "\n "
if parent:
msg = msg + "{} {} depends on ".format(
Expand All @@ -484,6 +497,9 @@ def describe_trigger(parent):
else:
msg = msg + "The user requested "
msg = msg + req.format_for_error()
for key in relevant_constraints:
description = "{}{}".format(key, constraints[key].specifier)
msg += "\n The user requested constraint {}".format(description)

msg = msg + "\n\n" + \
"To fix this you could try to:\n" + \
Expand Down
2 changes: 1 addition & 1 deletion src/pip/_internal/resolution/resolvelib/resolver.py
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ def resolve(self, root_reqs, check_supported_wheels):
)

except ResolutionImpossible as e:
error = self.factory.get_installation_error(e)
error = self.factory.get_installation_error(e, constraints)
six.raise_from(error, e)

req_set = RequirementSet(check_supported_wheels=check_supported_wheels)
Expand Down
4 changes: 2 additions & 2 deletions tests/functional/test_install_reqs.py
Original file line number Diff line number Diff line change
Expand Up @@ -358,7 +358,7 @@ def test_constraints_local_editable_install_causes_error(
assert 'Could not satisfy constraints' in result.stderr, str(result)
else:
# Because singlemodule only has 0.0.1 available.
assert 'No matching distribution found' in result.stderr, str(result)
assert 'Cannot install singlemodule 0.0.1' in result.stderr, str(result)


@pytest.mark.network
Expand Down Expand Up @@ -387,7 +387,7 @@ def test_constraints_local_install_causes_error(
assert 'Could not satisfy constraints' in result.stderr, str(result)
else:
# Because singlemodule only has 0.0.1 available.
assert 'No matching distribution found' in result.stderr, str(result)
assert 'Cannot install singlemodule 0.0.1' in result.stderr, str(result)


def test_constraints_constrain_to_local_editable(
Expand Down
2 changes: 1 addition & 1 deletion tests/functional/test_new_resolver.py
Original file line number Diff line number Diff line change
Expand Up @@ -715,7 +715,7 @@ def test_new_resolver_constraint_on_dependency(script):
@pytest.mark.parametrize(
"constraint_version, expect_error, message",
[
("1.0", True, "ERROR: No matching distribution found for foo 2.0"),
("1.0", True, "Cannot install foo 2.0"),
("2.0", False, "Successfully installed foo-2.0"),
],
)
Expand Down

0 comments on commit fa97998

Please sign in to comment.