mirror of
https://github.com/astral-sh/uv.git
synced 2025-10-02 15:01:16 +00:00
uv-resolver: fix bug in marker disjointness checking
I found this while testing the tracking of marker expressions across resolver forks. Namely, given sys_platform == 'darwin' and implementation_name == 'pypy' And: sys_platform == 'bar' or implementation_name == 'foo' These should be disjoint, but the disjointness checker was reporting them as overlapping. I fixed this by giving handling of disjunctions higher precedence than conjunctions, although I am not 100% confident that this is correct for all cases.
This commit is contained in:
parent
407f1e370b
commit
dbb12bcfe4
1 changed files with 13 additions and 4 deletions
|
@ -18,14 +18,14 @@ use pubgrub::range::Range as PubGrubRange;
|
|||
pub(crate) fn is_disjoint(first: &MarkerTree, second: &MarkerTree) -> bool {
|
||||
let (expr1, expr2) = match (first, second) {
|
||||
(MarkerTree::Expression(expr1), MarkerTree::Expression(expr2)) => (expr1, expr2),
|
||||
// `And` expressions are disjoint if any clause is disjoint.
|
||||
(other, MarkerTree::And(exprs)) | (MarkerTree::And(exprs), other) => {
|
||||
return exprs.iter().any(|tree1| is_disjoint(tree1, other))
|
||||
}
|
||||
// `Or` expressions are disjoint if all clauses are disjoint.
|
||||
(other, MarkerTree::Or(exprs)) | (MarkerTree::Or(exprs), other) => {
|
||||
return exprs.iter().all(|tree1| is_disjoint(tree1, other))
|
||||
}
|
||||
// `And` expressions are disjoint if any clause is disjoint.
|
||||
(other, MarkerTree::And(exprs)) | (MarkerTree::And(exprs), other) => {
|
||||
return exprs.iter().any(|tree1| is_disjoint(tree1, other));
|
||||
}
|
||||
};
|
||||
|
||||
match (expr1, expr2) {
|
||||
|
@ -529,6 +529,15 @@ mod tests {
|
|||
"os_name == 'a' or platform_version == '1'",
|
||||
"os_name == 'a' or platform_version == '2'"
|
||||
));
|
||||
|
||||
assert!(is_disjoint(
|
||||
"sys_platform == 'darwin' and implementation_name == 'pypy'",
|
||||
"sys_platform == 'bar' or implementation_name == 'foo'",
|
||||
));
|
||||
assert!(is_disjoint(
|
||||
"sys_platform == 'bar' or implementation_name == 'foo'",
|
||||
"sys_platform == 'darwin' and implementation_name == 'pypy'",
|
||||
));
|
||||
}
|
||||
|
||||
fn test_version_bounds_disjointness(version: &str) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue