Avoid enforcing extra-only constraints (#4570)

## Summary

In the dependency refactor (https://github.com/astral-sh/uv/pull/4430),
the logic for requirements and constraints was combined. Specifically,
we were applying constraints _before_ filtering on markers and extras,
and then applying that same filtering to the constraints. As a result,
constraints that should only be activated when an extra is enabled were
being enabled unconditionally.

Closes https://github.com/astral-sh/uv/issues/4569.
This commit is contained in:
Charlie Marsh 2024-06-26 18:52:46 -04:00 committed by GitHub
parent a8c28c4612
commit bbbe1f3968
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 77 additions and 12 deletions

View file

@ -1302,15 +1302,6 @@ impl<InstalledPackages: InstalledPackagesProvider> ResolverState<InstalledPackag
) -> impl Iterator<Item = &'a Requirement> {
self.overrides
.apply(dependencies)
.flat_map(|requirement| {
iter::once(requirement).chain(
// If the requirement was constrained, add those constraints.
self.constraints
.get(&requirement.name)
.into_iter()
.flatten(),
)
})
.filter(move |requirement| {
// If the requirement would not be selected with any Python version
// supported by the root, skip it.
@ -1353,8 +1344,50 @@ impl<InstalledPackages: InstalledPackagesProvider> ResolverState<InstalledPackag
}
}
}
true
})
.flat_map(move |requirement| {
iter::once(requirement).chain(
self.constraints
.get(&requirement.name)
.into_iter()
.flatten()
.filter(move |constraint| {
if !satisfies_requires_python(self.requires_python.as_ref(), constraint) {
trace!(
"skipping {constraint} because of Requires-Python {requires_python}",
requires_python = self.requires_python.as_ref().unwrap()
);
return false;
}
if !possible_to_satisfy_markers(markers, constraint) {
trace!("skipping {constraint} because of context resolver markers {markers}");
return false;
}
// If the constraint isn't relevant for the current platform, skip it.
match extra {
Some(source_extra) => {
if !constraint.evaluate_markers(
self.markers.as_ref(),
std::slice::from_ref(source_extra),
) {
return false;
}
}
None => {
if !constraint.evaluate_markers(self.markers.as_ref(), &[]) {
return false;
}
}
}
true
}),
)
})
}
/// Fetch the metadata for a stream of packages and versions.