From 17452e3e647b70a84d6655edc4e577e7a09864f9 Mon Sep 17 00:00:00 2001 From: Charlie Marsh Date: Sun, 7 Jan 2024 12:40:22 -0500 Subject: [PATCH] Simplify ranges in pre-release hints (#825) Closes https://github.com/astral-sh/puffin/issues/807. --- .../puffin-cli/tests/pip_install_scenarios.rs | 4 +- crates/puffin-resolver/src/error.rs | 6 +-- crates/puffin-resolver/src/pubgrub/mod.rs | 2 +- crates/puffin-resolver/src/pubgrub/report.rs | 41 ++++++------------- 4 files changed, 17 insertions(+), 36 deletions(-) diff --git a/crates/puffin-cli/tests/pip_install_scenarios.rs b/crates/puffin-cli/tests/pip_install_scenarios.rs index ebc244d0e..8370df073 100644 --- a/crates/puffin-cli/tests/pip_install_scenarios.rs +++ b/crates/puffin-cli/tests/pip_install_scenarios.rs @@ -1469,7 +1469,7 @@ fn requires_transitive_prerelease_and_stable_dependency_many_versions() -> Resul And because a==1.0.0 depends on c>=2.0.0b1 and there is no version of a available matching <1.0.0 | >1.0.0, b *, a * are incompatible. And because root depends on b and root depends on a, version solving failed. - hint: c was requested with a pre-release marker (e.g., >=2.0.0b1, <=3.0.0), but pre-releases weren't enabled (try: `--prerelease=allow`) + hint: c was requested with a pre-release marker (e.g., >=2.0.0b1), but pre-releases weren't enabled (try: `--prerelease=allow`) "###); }); @@ -1566,7 +1566,7 @@ fn requires_transitive_prerelease_and_stable_dependency_many_versions_holes() -> ╰─▶ Because there is no version of c available matching >1.0.0, <2.0.0a5 | >2.0.0a7, <2.0.0b1 | >2.0.0b1, <2.0.0b5 and a==1.0.0 depends on c>1.0.0, <2.0.0a5 | >2.0.0a7, <2.0.0b1 | >2.0.0b1, <2.0.0b5, a==1.0.0 is forbidden. And because there is no version of a available matching <1.0.0 | >1.0.0 and root depends on a, version solving failed. - hint: c was requested with a pre-release marker (e.g., >1.0.0, <2.0.0a5 | >2.0.0a5, <2.0.0a6 | >2.0.0a6, <2.0.0a7 | >2.0.0a7, <2.0.0b1 | >2.0.0b1, <2.0.0b5), but pre-releases weren't enabled (try: `--prerelease=allow`) + hint: c was requested with a pre-release marker (e.g., >1.0.0, <2.0.0a5 | >2.0.0a7, <2.0.0b1 | >2.0.0b1, <2.0.0b5), but pre-releases weren't enabled (try: `--prerelease=allow`) "###); }); diff --git a/crates/puffin-resolver/src/error.rs b/crates/puffin-resolver/src/error.rs index 999654ba1..3f5a0faa0 100644 --- a/crates/puffin-resolver/src/error.rs +++ b/crates/puffin-resolver/src/error.rs @@ -15,9 +15,7 @@ use puffin_traits::OnceMap; use pypi_types::BaseUrl; use crate::candidate_selector::CandidateSelector; -use crate::pubgrub::{ - PubGrubHints, PubGrubPackage, PubGrubPython, PubGrubReportFormatter, PubGrubVersion, -}; +use crate::pubgrub::{PubGrubPackage, PubGrubPython, PubGrubReportFormatter, PubGrubVersion}; use crate::python_requirement::PythonRequirement; use crate::version_map::VersionMap; @@ -146,7 +144,7 @@ impl std::fmt::Display for NoSolutionError { // Include any additional hints. if let Some(selector) = &self.selector { - for hint in PubGrubHints::from_derivation_tree(&self.derivation_tree, selector).iter() { + for hint in formatter.hints(&self.derivation_tree, selector) { write!(f, "\n\n{hint}")?; } } diff --git a/crates/puffin-resolver/src/pubgrub/mod.rs b/crates/puffin-resolver/src/pubgrub/mod.rs index 359505a66..d8dba9711 100644 --- a/crates/puffin-resolver/src/pubgrub/mod.rs +++ b/crates/puffin-resolver/src/pubgrub/mod.rs @@ -2,7 +2,7 @@ pub(crate) use crate::pubgrub::dependencies::PubGrubDependencies; pub(crate) use crate::pubgrub::distribution::PubGrubDistribution; pub(crate) use crate::pubgrub::package::{PubGrubPackage, PubGrubPython}; pub(crate) use crate::pubgrub::priority::{PubGrubPriorities, PubGrubPriority}; -pub(crate) use crate::pubgrub::report::{PubGrubHints, PubGrubReportFormatter}; +pub(crate) use crate::pubgrub::report::PubGrubReportFormatter; pub(crate) use crate::pubgrub::specifier::PubGrubSpecifier; pub(crate) use crate::pubgrub::version::{PubGrubVersion, MIN_VERSION}; diff --git a/crates/puffin-resolver/src/pubgrub/report.rs b/crates/puffin-resolver/src/pubgrub/report.rs index 72d4e7bb2..e736f1058 100644 --- a/crates/puffin-resolver/src/pubgrub/report.rs +++ b/crates/puffin-resolver/src/pubgrub/report.rs @@ -131,6 +131,7 @@ impl ReportFormatter> for PubGrubReportFor } impl PubGrubReportFormatter<'_> { + /// Simplify a [`Range`] of versions using the available versions for a package. fn simplify_set<'a>( &self, set: &'a Range, @@ -142,20 +143,17 @@ impl PubGrubReportFormatter<'_> { Cow::Owned(set.simplify(self.available_versions.get(package).into_iter().flatten())) } } -} -/// A set of hints to help users resolve errors by providing additional context or modifying -/// their requirements. -#[derive(Debug, Default)] -pub(crate) struct PubGrubHints(FxHashSet); - -impl PubGrubHints { - /// Create a set of hints from a derivation tree. - pub(crate) fn from_derivation_tree( + /// Generate the [`PubGrubHints`] for a derivation tree. + /// + /// The [`PubGrubHints`] help users resolve errors by providing additional context or modifying + /// their requirements. + pub(crate) fn hints( + &self, derivation_tree: &DerivationTree>, selector: &CandidateSelector, - ) -> Self { - let mut hints = Self::default(); + ) -> FxHashSet { + let mut hints = FxHashSet::default(); match derivation_tree { DerivationTree::External(external) => match external { External::NoVersions(package, set) => { @@ -185,7 +183,7 @@ impl PubGrubHints { if !allowed_prerelease { hints.insert(PubGrubHint::NoVersionsWithPreRelease { package: package.clone(), - range: set.clone(), + range: self.simplify_set(set, package).into_owned(), }); } } @@ -196,27 +194,12 @@ impl PubGrubHints { External::FromDependencyOf(..) => {} }, DerivationTree::Derived(derived) => { - hints.extend(Self::from_derivation_tree(&derived.cause1, selector)); - hints.extend(Self::from_derivation_tree(&derived.cause2, selector)); + hints.extend(self.hints(&derived.cause1, selector)); + hints.extend(self.hints(&derived.cause2, selector)); } } hints } - - /// Iterate over the hints in the set. - pub(crate) fn iter(&self) -> impl Iterator { - self.0.iter() - } - - /// Insert a hint into the set. - fn insert(&mut self, hint: PubGrubHint) -> bool { - self.0.insert(hint) - } - - /// Extend the set with another set of hints. - fn extend(&mut self, hints: Self) { - self.0.extend(hints.0); - } } #[derive(Derivative, Debug, Clone)]