Special case "only available" bounds in resolver errors#6071
Closed
Special case "only available" bounds in resolver errors#6071
Conversation
zanieb
commented
Aug 13, 2024
| if let [(lower, upper)] = segments.as_slice() { | ||
| // If the bound is inclusive, and the version is _not_ | ||
| // available, change it to an exclusive bound. | ||
| let lower = match lower { |
Member
Author
There was a problem hiding this comment.
Suggestions welcome on the pattern here, but I'm going to open an issue to follow-up to make this reusable in the multi-segment case as well.
6bb48e7 to
d227fcb
Compare
d227fcb to
8eed661
Compare
We're using the wrong type here, which never mattered since it was a single bound but will matter in the future :)
Member
Author
|
#6118 is more comprehensive and would conflict. |
zanieb
added a commit
that referenced
this pull request
Aug 15, 2024
Includes the changes from #6071 but takes them way further. When we have the set of available versions for a package, we can do a much better job displaying an error. For example: ``` ❯ uv add 'httpx>999,<9999' × No solution found when resolving dependencies: ╰─▶ Because only the following versions of httpx are available: httpx<=999 httpx>=9999 and example==0.1.0 depends on httpx>999,<9999, we can conclude that example==0.1.0 cannot be used. And because only example==0.1.0 is available and you require example, we can conclude that the requirements are unsatisfiable. ``` The resolver has demonstrated that the requested range cannot be used because there are only versions in ranges _outside_ the requested range. However, the display of the range of available versions is pretty bad! We say there are versions of httpx available in ranges that definitely have no versions available. With this pull request, the error becomes: ``` ❯ uv add 'httpx>999,<9999' × No solution found when resolving dependencies: ╰─▶ Because only httpx<=1.0.0b0 is available and example depends on httpx>999,<9999, we can conclude that example's requirements are unsatisfiable. And because your workspace requires example, we can conclude that your workspace's requirements are unsatisfiable. ``` We achieve this by: 1. Dropping ranges disjoint with the range of available versions, e.g., this removes `httpx>=9999` 2. Replacing ranges that capture the _entire_ range of available versions with the smaller range, e.g., this replaces `httpx<=999` with `<=1.0.0b0`. ~Note that when we perform (2), we may include an additional bound that is not relevant, e.g., we include the lower bound of `>=0.6.7`. This is a bit extraneous, but I don't think it's confusing. We can consider some advanced logic to avoid that later.~ (edit: I did this, it wasn't hard) We also improve error messages when there is _only_ one version available by showing that version instead of a range.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
So, this is a little nuanced, but it confused me a couple times and I'm poking around in this code so I figured I'd give it a try.
In the following:
We say
only httpx<=9999 is available, which suggests thathttpx 9999is available — but it's not, and we know that. The problem is that we naively take the complement of the requirement (httpx>9999).Here, we special case inclusive bounds to check if the version in question is actually available — if not, we switch to an exclusive bound.
Note this also applies to the reverse case
However, for simplicity, I haven't tackled the case where we display multiple version segments yet. So for more complex requests, our messaging is still confusing:
This will require further refactoring, which I'll track in a new issue.