Skip to content

Commit

Permalink
Fix redundant enumeration of all package versions in some resolver er…
Browse files Browse the repository at this point in the history
…rors
  • Loading branch information
zanieb committed Dec 13, 2024
1 parent 9ced13e commit 210c3a7
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 10 deletions.
57 changes: 57 additions & 0 deletions crates/uv-resolver/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -336,6 +336,7 @@ impl std::fmt::Display for NoSolutionError {
}

collapse_unavailable_versions(&mut tree);
collapse_redundant_no_versions(&mut tree);
collapse_redundant_depends_on_no_versions(&mut tree);

if should_display_tree {
Expand Down Expand Up @@ -422,6 +423,62 @@ fn display_tree_inner(
}
}

fn collapse_redundant_no_versions(
tree: &mut DerivationTree<PubGrubPackage, Range<Version>, UnavailableReason>,
) {
match tree {
DerivationTree::External(_) => {}
DerivationTree::Derived(derived) => {
match (
Arc::make_mut(&mut derived.cause1),
Arc::make_mut(&mut derived.cause2),
) {
// If we have a node for a package with no versions...
(
DerivationTree::External(External::NoVersions(package, versions)),
ref mut other,
)
| (
ref mut other,
DerivationTree::External(External::NoVersions(package, versions)),
) => {
// First, always recursively visit the other side of the tree
collapse_redundant_no_versions(other);

let DerivationTree::Derived(derived) = other else {
return;
};

// If the range in the conclusion (terms) matches the range of no versions,
// then we'll drop this node
let Some(Term::Positive(term)) = derived.terms.get(package) else {
return;
};
let versions = versions.complement();

// If we're disqualifying a single version, this is important to retain, e.g,
// for `only foo==1.0.0 is available`
if versions.as_singleton().is_some() {
return;
}

if *term != versions {
return;
}

// Replace this node with the other tree
*tree = other.clone();
}
// If not, just recurse
_ => {
collapse_redundant_no_versions(Arc::make_mut(&mut derived.cause1));
collapse_redundant_no_versions(Arc::make_mut(&mut derived.cause2));
}
}
}
}
}

/// Given a [`DerivationTree`], collapse any `NoVersion` incompatibilities for workspace members
/// to avoid saying things like "only <workspace-member>==0.1.0 is available".
fn collapse_no_versions_of_workspace_members(
Expand Down
11 changes: 1 addition & 10 deletions crates/uv/tests/it/pip_compile.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13107,16 +13107,7 @@ fn compile_enumerate_no_versions() -> Result<()> {
----- stderr -----
× No solution found when resolving dependencies:
╰─▶ Because the current Python version (3.10.15) does not satisfy Python>=3.11,<4.0 and all versions of rooster-blue depend on Python>=3.11,<4.0, we can conclude that all versions of rooster-blue cannot be used.
And because only the following versions of rooster-blue are available:
rooster-blue==0.0.1
rooster-blue==0.0.2
rooster-blue==0.0.3
rooster-blue==0.0.4
rooster-blue==0.0.5
rooster-blue==0.0.6
rooster-blue==0.0.7
rooster-blue==0.0.8
and you require rooster-blue, we can conclude that your requirements are unsatisfiable.
And because you require rooster-blue, we can conclude that your requirements are unsatisfiable.
"###);

Ok(())
Expand Down

0 comments on commit 210c3a7

Please sign in to comment.