Skip to content

Commit 917ecad

Browse files
committed
Show constraint in error message
1 parent e17ddea commit 917ecad

File tree

4 files changed

+31
-15
lines changed

4 files changed

+31
-15
lines changed

src/pip/_internal/resolution/resolvelib/factory.py

+27-11
Original file line numberDiff line numberDiff line change
@@ -404,8 +404,24 @@ def _report_requires_python_error(
404404
)
405405
return UnsupportedPythonVersion(message)
406406

407-
def get_installation_error(self, e):
408-
# type: (ResolutionImpossible) -> InstallationError
407+
def _report_single_requirement_conflict(self, req, parent):
408+
# type: (Requirement, Candidate) -> DistributionNotFound
409+
if parent is None:
410+
req_disp = str(req)
411+
else:
412+
req_disp = f"{req} (from {parent.name})"
413+
logger.critical(
414+
"Could not find a version that satisfies the requirement %s",
415+
req_disp,
416+
)
417+
return DistributionNotFound(f"No matching distribution found for {req}")
418+
419+
def get_installation_error(
420+
self,
421+
e, # type: ResolutionImpossible
422+
constraints, # type: Dict[str, Constraint]
423+
):
424+
# type: (...) -> InstallationError
409425

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

@@ -425,15 +441,8 @@ def get_installation_error(self, e):
425441
# satisfied. We just report that case.
426442
if len(e.causes) == 1:
427443
req, parent = e.causes[0]
428-
if parent is None:
429-
req_disp = str(req)
430-
else:
431-
req_disp = f"{req} (from {parent.name})"
432-
logger.critical(
433-
"Could not find a version that satisfies the requirement %s",
434-
req_disp,
435-
)
436-
return DistributionNotFound(f"No matching distribution found for {req}")
444+
if req.name not in constraints:
445+
return self._report_single_requirement_conflict(req, parent)
437446

438447
# OK, we now have a list of requirements that can't all be
439448
# satisfied at once.
@@ -475,13 +484,20 @@ def describe_trigger(parent):
475484
)
476485
logger.critical(msg)
477486
msg = "\nThe conflict is caused by:"
487+
488+
relevant_constraints = set()
478489
for req, parent in e.causes:
490+
if req.name in constraints:
491+
relevant_constraints.add(req.name)
479492
msg = msg + "\n "
480493
if parent:
481494
msg = msg + "{} {} depends on ".format(parent.name, parent.version)
482495
else:
483496
msg = msg + "The user requested "
484497
msg = msg + req.format_for_error()
498+
for key in relevant_constraints:
499+
spec = constraints[key].specifier
500+
msg += f"\n The user requested (constraint) {key}{spec}"
485501

486502
msg = (
487503
msg

src/pip/_internal/resolution/resolvelib/resolver.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ def resolve(self, root_reqs, check_supported_wheels):
122122
)
123123

124124
except ResolutionImpossible as e:
125-
error = self.factory.get_installation_error(e)
125+
error = self.factory.get_installation_error(e, constraints)
126126
six.raise_from(error, e)
127127

128128
req_set = RequirementSet(check_supported_wheels=check_supported_wheels)

tests/functional/test_install_reqs.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -357,7 +357,7 @@ def test_constraints_local_editable_install_causes_error(
357357
assert 'Could not satisfy constraints' in result.stderr, str(result)
358358
else:
359359
# Because singlemodule only has 0.0.1 available.
360-
assert 'No matching distribution found' in result.stderr, str(result)
360+
assert 'Cannot install singlemodule 0.0.1' in result.stderr, str(result)
361361

362362

363363
@pytest.mark.network
@@ -386,7 +386,7 @@ def test_constraints_local_install_causes_error(
386386
assert 'Could not satisfy constraints' in result.stderr, str(result)
387387
else:
388388
# Because singlemodule only has 0.0.1 available.
389-
assert 'No matching distribution found' in result.stderr, str(result)
389+
assert 'Cannot install singlemodule 0.0.1' in result.stderr, str(result)
390390

391391

392392
def test_constraints_constrain_to_local_editable(

tests/functional/test_new_resolver.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -687,7 +687,7 @@ def test_new_resolver_constraint_on_dependency(script):
687687
@pytest.mark.parametrize(
688688
"constraint_version, expect_error, message",
689689
[
690-
("1.0", True, "ERROR: No matching distribution found for foo 2.0"),
690+
("1.0", True, "Cannot install foo 2.0"),
691691
("2.0", False, "Successfully installed foo-2.0"),
692692
],
693693
)

0 commit comments

Comments
 (0)