-
Notifications
You must be signed in to change notification settings - Fork 765
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Allow conflicting locals when forking #5104
Conversation
20a0b92
to
0c7ce71
Compare
0c7ce71
to
8dffb13
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
w00t!
@@ -23,23 +23,26 @@ pub(crate) struct PubGrubDependency { | |||
/// even if this field is None where there is an override with a URL or there is a different | |||
/// requirement or constraint for the same package that has a URL. | |||
pub(crate) url: Option<VerbatimParsedUrl>, | |||
/// The local version for this requirement, if specified. | |||
pub(crate) local: Option<Version>, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it true that if local
is Some
, then Version::is_local
will always be true?
If so, then perhaps this could just be a Version
, and case analysis uses Version::is_local
or Version::local
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
After reading through the PR, I retract my suggestion. I see how this is very convenient because the acquisition of a local-only Version
is pretty naturally expressed via Option<Version>
. And I don't think you ever look at a local
and try to access its local segments, so there isn't really any redundant case analysis.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it true that if local is Some, then Version::is_local will always be true?
This is actually not true, because we also extract local versions from direct URL/path requirements.
# via torch | ||
torch==2.0.0+cpu ; platform_machine != 'x86_64' | ||
# via -r requirements.in | ||
torch==2.0.0+cu118 ; platform_machine == 'x86_64' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sweet
## Summary This fixes a few bugs introduced by #5104. I previously thought we could track conflicting locals the same way we track conflicting URLs in forks, but it turns out that ends up being very tricky. URL forks work because we prioritize directly URL requirements. We can't prioritize locals in the same way without conflicting with the URL prioritization (this may be possible but it's not trivial), so we run into issues where a correct resolution depends on the order in which dependencies are traversed. Instead, we track local versions across all forks in `Locals`. When applying a local version, we apply all locals with markers that intersect with the current fork. This way we end up applying some local versions without creating a fork. For example, given: ``` // pyproject.toml dependencies = [ "torch==2.0.0+cu118 ; platform_machine == 'x86_64'", ] // requirements.in torch==2.0.0 . ``` We choose `2.0.0+cu118` in all cases. However, if a disjoint fork is created based on local versions, the resolver will choose the most compatible local when it narrows to a specific fork. Thus we correctly respect local versions when forking: ``` // pyproject.toml dependencies = [ "torch==2.0.0+cu118 ; platform_machine == 'x86_64'", "torch==2.0.0+cpu ; platform_machine != 'x86_64'" ] // requirements.in torch==2.0.0 . ``` We should also be able to use a similar strategy for #5150. ## Test Plan This fixes #5220 locally for me, as well as a few other bugs that were not reported yet.
Summary
Currently, the
Locals
type relies on there being a single local version for a given package. With marker expressions this may not be true, a similar problem to #4435. This changes theLocals
type toForkLocals
, which tracks locals for a given fork. Local versions are now tracked onPubGrubRequirement
before forking.Resolves #4580.