diff --git a/crates/uv-resolver/src/resolver/batch_prefetch.rs b/crates/uv-resolver/src/resolver/batch_prefetch.rs index 558cdc2b7..deaeccd91 100644 --- a/crates/uv-resolver/src/resolver/batch_prefetch.rs +++ b/crates/uv-resolver/src/resolver/batch_prefetch.rs @@ -1,5 +1,6 @@ use std::cmp::min; +use itertools::Itertools; use pubgrub::range::Range; use rustc_hash::FxHashMap; use tokio::sync::mpsc::Sender; @@ -158,6 +159,10 @@ impl BatchPrefetcher { /// Each time we tried a version for a package, we register that here. pub(crate) fn version_tried(&mut self, package: PubGrubPackage) { + // Only track base packages, no virtual packages from extras. + if matches!(package, PubGrubPackage::Package(_, Some(_), _)) { + return; + } *self.tried_versions.entry(package).or_default() += 1; } @@ -173,4 +178,23 @@ impl BatchPrefetcher { || (num_tried >= 20 && num_tried - previous_prefetch >= 20); (num_tried, do_prefetch) } + + /// Log stats about how many versions we tried. + /// + /// Note that they may be inflated when we count the same version repeatedly during + /// backtracking. + pub(crate) fn log_tried_versions(&self) { + let total_versions: usize = self.tried_versions.values().sum(); + let mut tried_versions: Vec<_> = self.tried_versions.iter().collect(); + tried_versions.sort_by(|(p1, c1), (p2, c2)| { + c1.cmp(c2) + .reverse() + .then(p1.to_string().cmp(&p2.to_string())) + }); + let counts = tried_versions + .iter() + .map(|(package, count)| format!("{package} {count}")) + .join(", "); + debug!("Tried {total_versions} versions: {counts}"); + } } diff --git a/crates/uv-resolver/src/resolver/mod.rs b/crates/uv-resolver/src/resolver/mod.rs index 74a564682..9832c6dd0 100644 --- a/crates/uv-resolver/src/resolver/mod.rs +++ b/crates/uv-resolver/src/resolver/mod.rs @@ -14,7 +14,7 @@ use pubgrub::range::Range; use pubgrub::solver::{Incompatibility, State}; use rustc_hash::{FxHashMap, FxHashSet}; use tokio_stream::wrappers::ReceiverStream; -use tracing::{debug, info_span, instrument, trace, warn, Instrument}; +use tracing::{debug, enabled, info_span, instrument, trace, warn, Instrument, Level}; use distribution_types::{ BuiltDist, Dist, DistributionMetadata, IncompatibleDist, IncompatibleSource, IncompatibleWheel, @@ -323,6 +323,9 @@ impl< priorities.get(package).unwrap_or_default() }) else { + if enabled!(Level::DEBUG) { + prefetcher.log_tried_versions(); + } let selection = state.partial_solution.extract_solution(); return ResolutionGraph::from_state( &selection, @@ -482,6 +485,9 @@ impl< .iter() .any(|(dependency, _)| dependency == package) => { + if enabled!(Level::DEBUG) { + prefetcher.log_tried_versions(); + } return Err(PubGrubError::SelfDependency { package: package.clone(), version: version.clone(),