-
Notifications
You must be signed in to change notification settings - Fork 1.2k
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
Conflicting groups should handle conflicting inclusions automatically #12005
Conversation
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.
I've moved this file so that I can import DependencyGroups
in conflicts.rs
. It would have caused a circular dependency in uv-workspace
.
} | ||
|
||
// Propagate canonical items through the graph and populate substitutions. | ||
// FIXME: Have we already done cycle detection before this method was |
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.
Can we assume cycle detection before this point? Otherwise, we'll have to return an error
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.
There's a failing test that wasn't running locally for some reason that shows we can't assume it at this point. I'll update.
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.
What I've done now is to just return if there's a Cycle
error on toposort
. I've left a FIXME
comment indicating that we're currently bailing and allowing more detailed include cycle detection downstream. Is this the behavior we want? If so, I'll remove the FIXME
tag.
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.
Hmmm cc @zanieb
One thing that strikes me here is that the cycle detection error would only kick in when a relevant conflicting group is declared? What happens if there aren't any conflicts declared? Is there cycle detection happening somewhere else?
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.
Cycle detection is happening somewhere, maybe in the resolver? But that happens after this code is called. With this new version where I just return (no error) when toposort()
returns an error, then only the original conflict sets are sent along.
But it does seem weird to silently swallow the error. The reason I don't want it propagated is because better cycle detection happens elsewhere ("there was a cycle" vs. "there was a cycle: dev -> test -> dev"). So I could either warn the user in this method or match at the caller and warn there. Do either of those options make sense?
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.
I think what you're doing now is probably reasonable with a comment explaining what's going on here (basically, what you just said). @zanieb might have a different opinion though!
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.
I don't know what our current behavior for cycles is. Are we talking about cycles in inclusions or cycles in the conflicts?
-
If
dev
includestest
andtest
includesdev
don't we have a consistent set of dependencies? (just the union oftest
anddev
?) -
Similarly, if
test
is marked as conflicting with some other groupfoo
thendev
conflicts withfoo
too, the cycle doesn't matter here. -
If
test
is marked as conflicting withdev
, now the cycle is a problem because... they include each other and can't conflict. This applies to longer chains too, e.g., if we havetest -> foo -> dev -> test
a conflict betweentest
anddev
is "invalid".
If we don't have test coverage for each of these cases, we should add it. In reply to
One thing that strikes me here is that the cycle detection error would only kick in when a relevant conflicting group is declared?
This seems fine, because this form of cycle (3) is the only one that creates an unresolvable situation?
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.
Unless I'm misunderstanding, cycles in dependency groups are an error. Per the PEP:
Dependency Group Includes MUST NOT include cycles, and tools SHOULD report an error if they detect a cycle.
I think we have an DependencyGroupCycle
error.
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.
Yeah, on main
we definitely error on cycles. That's the behavior I'm relying on when just returning from the conflict expansion method when detecting a cycle during toposort
.
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.
Oh, thanks for the correction. Maybe I was just thinking about feedback I wrote on the PEP.
d196583
to
6db0af9
Compare
6db0af9
to
65f059f
Compare
c2aeec1
to
7f88996
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.
Nice work!
The failing duplicate_torch_and_sympy_because_of_wrong_inferences
is somewhat worrisome, because that doesn't use dependency groups at all. So in theory, it shouldn't be impacted by the work here?
In your code, I wonder if something wonky is happening when no DependencyGroupSpecifier::IncludeGroup
are found and thus no edges are added?
} | ||
|
||
// Propagate canonical items through the graph and populate substitutions. | ||
// FIXME: Have we already done cycle detection before this method was |
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.
Hmmm cc @zanieb
One thing that strikes me here is that the cycle detection error would only kick in when a relevant conflicting group is declared? What happens if there aren't any conflicts declared? Is there cycle detection happening somewhere else?
00df880
to
05c6bea
Compare
05c6bea
to
5e28d63
Compare
5e28d63
to
23942fb
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.
Looks good from my perspective modulo the Cargo.lock
changes which we should verify before merging.
----- stderr ----- | ||
Resolved 5 packages in [TIME] | ||
error: Groups `dev` and `dev2` are incompatible with the transitively inferred conflicts: {`example:dev`, `example:dev2`} |
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.
I don't quite understand this error, are we just repeating the groups here at the end? What's the value of that?
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.
I believe this is identical to the existing error we show in these cases, except "transitively" has been inserted. Perhaps this should be hashed out separately from this PR, since it doesn't seem to be a change? But for reference, the set at the end can be larger than "just" these two items. The set at the end is of arbitrary size, and the groups we list at the start are the activated, conflicting members.
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.
Oh, if it's not changing here that's fine and we can revisit it separately — I just looked at the test case not the implementation.
006ee40
to
32cac26
Compare
This adds support for inferring dependency group conflict sets from the directly defined conflicts in configuration. For example, if you declare a conflict between groups
alpha
andbeta
anddev
includesbeta
, then we will infer a conflict betweendev
andalpha
. We will also handle a conflict between two groups if they transitively include groups that conflict with each other. See #11232 for more details.Closes #11232