Skip to content

Commit 7475e75

Browse files
committed
Don't prefetch unreachable packages
When batch prefetching we can fetch versions we know that are incompatible. In the following example, we were prefetching sentry-kafka-schemas below version 1.50.0. ``` python-rapidjson<=1.20,>=1.4 sentry-kafka-schemas<=0.1.113,>=0.1.50 ``` Using a new pubgrub interface from astral-sh/pubgrub#32, we can avoid those prefetches by asking for incompatibilities that won't change anymore (those with root).
1 parent d930367 commit 7475e75

File tree

4 files changed

+20
-4
lines changed

4 files changed

+20
-4
lines changed

Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ pathdiff = { version = "0.2.1" }
125125
petgraph = { version = "0.6.5" }
126126
platform-info = { version = "2.0.3" }
127127
proc-macro2 = { version = "1.0.86" }
128-
pubgrub = { git = "https://github.com/astral-sh/pubgrub", rev = "19c77268c0ad5f69d7e12126e0cfacfbba466481" }
128+
pubgrub = { git = "https://github.com/astral-sh/pubgrub", rev = "7243f4faf8e54837aa8a401a18406e7173de4ad5" }
129129
quote = { version = "1.0.37" }
130130
rayon = { version = "1.10.0" }
131131
reflink-copy = { version = "0.1.19" }

crates/uv-resolver/src/resolver/batch_prefetch.rs

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use std::cmp::min;
22

33
use itertools::Itertools;
4-
use pubgrub::Range;
4+
use pubgrub::{Range, Term};
55
use rustc_hash::FxHashMap;
66
use tokio::sync::mpsc::Sender;
77
use tracing::{debug, trace};
@@ -49,6 +49,7 @@ impl BatchPrefetcher {
4949
index: Option<&IndexUrl>,
5050
version: &Version,
5151
current_range: &Range<Version>,
52+
unchangeable_constraints: Option<&Term<Range<Version>>>,
5253
python_requirement: &PythonRequirement,
5354
request_sink: &Sender<Request>,
5455
in_memory: &InMemoryIndex,
@@ -119,11 +120,22 @@ impl BatchPrefetcher {
119120
}
120121
}
121122
BatchPrefetchStrategy::InOrder { previous } => {
122-
let range = if selector.use_highest_version(name) {
123+
let mut range = if selector.use_highest_version(name) {
123124
Range::strictly_lower_than(previous)
124125
} else {
125126
Range::strictly_higher_than(previous)
126127
};
128+
// If we have constraints from root, don't go beyond those. Example: We are
129+
// prefetching for foo 1.60 and have a dependency for `foo>=1.50`, so we should
130+
// only prefetch 1.60 to 1.50, knowing 1.49 will always be rejected.
131+
if let Some(unchangeable_constraints) = unchangeable_constraints {
132+
range = match unchangeable_constraints {
133+
Term::Positive(constraints) => range.intersection(constraints),
134+
Term::Negative(negative_constraints) => {
135+
range.intersection(&negative_constraints.complement())
136+
}
137+
};
138+
}
127139
if let Some(candidate) =
128140
selector.select_no_preference(name, &range, version_map, markers)
129141
{

crates/uv-resolver/src/resolver/mod.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -477,6 +477,10 @@ impl<InstalledPackages: InstalledPackagesProvider> ResolverState<InstalledPackag
477477
index,
478478
&version,
479479
term_intersection.unwrap_positive(),
480+
state
481+
.pubgrub
482+
.partial_solution
483+
.unchanging_term_for_package(&state.next),
480484
&state.python_requirement,
481485
&request_sink,
482486
&self.index,

0 commit comments

Comments
 (0)