Don't apply irrelevant constraints when validating site-packages (#5231)

## Summary

The current code was checking every constraint against every
requirement, regardless of whether they were applicable. In general,
this isn't a big deal, because this method is only used as a fast-path
to skip resolution -- so we just had way more false-negatives than we
should've when constraints were applied. But it's clearly wrong :)

## Test Plan

- `uv venv`
- `uv pip install flask`
- `uv pip install --verbose flask -c constraints.txt` (with `numpy<1.0`)

Prior to this change, Flask was reported as not satisfied.
This commit is contained in:
Charlie Marsh 2024-07-19 16:49:22 -04:00 committed by GitHub
parent 583a6e57f2
commit a253913288
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -266,6 +266,18 @@ impl SitePackages {
requirements: &[UnresolvedRequirementSpecification],
constraints: &[Requirement],
) -> Result<SatisfiesResult> {
// Collect the constraints.
let constraints: FxHashMap<&PackageName, Vec<&Requirement>> =
constraints
.iter()
.fold(FxHashMap::default(), |mut constraints, requirement| {
constraints
.entry(&requirement.name)
.or_default()
.push(requirement);
constraints
});
let mut stack = Vec::with_capacity(requirements.len());
let mut seen = FxHashSet::with_capacity_and_hasher(requirements.len(), FxBuildHasher);
@ -306,8 +318,9 @@ impl SitePackages {
}
RequirementSatisfaction::Satisfied => {}
}
// Validate that the installed version satisfies the constraints.
for constraint in constraints {
for constraint in constraints.get(&distribution.name()).into_iter().flatten() {
match RequirementSatisfaction::check(distribution, &constraint.source)? {
RequirementSatisfaction::Mismatch
| RequirementSatisfaction::OutOfDate