From a2539132880c95ef0e0562864fa80bfd0dba57a3 Mon Sep 17 00:00:00 2001 From: Charlie Marsh Date: Fri, 19 Jul 2024 16:49:22 -0400 Subject: [PATCH] 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. --- crates/uv-installer/src/site_packages.rs | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/crates/uv-installer/src/site_packages.rs b/crates/uv-installer/src/site_packages.rs index 621fe7360..002657afb 100644 --- a/crates/uv-installer/src/site_packages.rs +++ b/crates/uv-installer/src/site_packages.rs @@ -266,6 +266,18 @@ impl SitePackages { requirements: &[UnresolvedRequirementSpecification], constraints: &[Requirement], ) -> Result { + // 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