Skip to content

Commit

Permalink
Next iteration of message
Browse files Browse the repository at this point in the history
  • Loading branch information
pfmoore committed Jun 17, 2020
1 parent a42ed23 commit 1f4b538
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 19 deletions.
54 changes: 36 additions & 18 deletions src/pip/_internal/resolution/resolvelib/factory.py
Expand Up @@ -391,35 +391,53 @@ def readable_form(cand):
# type: (Candidate) -> str
return "{} {}".format(cand.name, cand.version)

if any(parent for _, parent in e.causes):
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:"
triggers = []
for req, parent in e.causes:
if parent is None:
# This is a root requirement, so we can report it directly
trigger = req.format_for_error()
else:
ireq = parent.get_install_requirement()
if ireq and ireq.comes_from:
trigger = "{}".format(
ireq.comes_from.name )
else:
trigger = "{} {}".format(
parent.name,
parent.version
)
triggers.append(trigger)

if triggers:
info = text_join(triggers)
else:
msg = "The following requirements are inconsistent:"
info = "the requested packages"

msg = "Cannot install {} because these package versions " \
"have conflicting dependencies.".format(info)
logger.critical(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 "
msg = msg + "{} {} depends on ".format(
parent.name,
parent.version
)
else:
msg = msg + "The user requested "
msg = msg + req.format_for_error()

msg = msg + "\n\n" + \
"There are a number of possible solutions. " + \
"For instructions on how to do these steps visit: " + \
"https://pypa.io/SomeLink"
"To fix this you could try to:\n" + \
"1. loosen the range of package versions you've specified\n" + \
"2. remove package versions to allow pip attempt to solve " + \
"the dependency conflict\n"

logger.critical(msg)
logger.info(msg)

return DistributionNotFound(
"No matching distribution found for " +
", ".join(sorted(set(r.name for r, _ in e.causes)))
"ResolutionImpossible For help visit: "
"https://pip.pypa.io/en/stable/user_guide/"
"#dependency-conflicts-resolution-impossible"
)
13 changes: 12 additions & 1 deletion src/pip/_internal/resolution/resolvelib/requirements.py
Expand Up @@ -69,7 +69,18 @@ def name(self):

def format_for_error(self):
# type: () -> str
return str(self)

# Convert comma-separated specifiers into "A, B, ..., F and G"
# This makes the specifier a bit more "human readable", without
# risking a change in meaning. (Hopefully! Not all edge cases have
# been checked)
parts = [s.strip() for s in str(self).split(",")]
if len(parts) == 0:
return ""
elif len(parts) == 1:
return parts[0]

return ", ".join(parts[:-1]) + " and " + parts[-1]

def get_candidate_lookup(self):
# type: () -> CandidateLookup
Expand Down

0 comments on commit 1f4b538

Please sign in to comment.