Simplify ranges in pre-release hints (#825)

Closes https://github.com/astral-sh/puffin/issues/807.
This commit is contained in:
Charlie Marsh 2024-01-07 12:40:22 -05:00 committed by GitHub
parent e6fcb9c4d3
commit 17452e3e64
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 17 additions and 36 deletions

View file

@ -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 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. 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. 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. 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`)
"###); "###);
}); });

View file

@ -15,9 +15,7 @@ use puffin_traits::OnceMap;
use pypi_types::BaseUrl; use pypi_types::BaseUrl;
use crate::candidate_selector::CandidateSelector; use crate::candidate_selector::CandidateSelector;
use crate::pubgrub::{ use crate::pubgrub::{PubGrubPackage, PubGrubPython, PubGrubReportFormatter, PubGrubVersion};
PubGrubHints, PubGrubPackage, PubGrubPython, PubGrubReportFormatter, PubGrubVersion,
};
use crate::python_requirement::PythonRequirement; use crate::python_requirement::PythonRequirement;
use crate::version_map::VersionMap; use crate::version_map::VersionMap;
@ -146,7 +144,7 @@ impl std::fmt::Display for NoSolutionError {
// Include any additional hints. // Include any additional hints.
if let Some(selector) = &self.selector { 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}")?; write!(f, "\n\n{hint}")?;
} }
} }

View file

@ -2,7 +2,7 @@ pub(crate) use crate::pubgrub::dependencies::PubGrubDependencies;
pub(crate) use crate::pubgrub::distribution::PubGrubDistribution; pub(crate) use crate::pubgrub::distribution::PubGrubDistribution;
pub(crate) use crate::pubgrub::package::{PubGrubPackage, PubGrubPython}; pub(crate) use crate::pubgrub::package::{PubGrubPackage, PubGrubPython};
pub(crate) use crate::pubgrub::priority::{PubGrubPriorities, PubGrubPriority}; 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::specifier::PubGrubSpecifier;
pub(crate) use crate::pubgrub::version::{PubGrubVersion, MIN_VERSION}; pub(crate) use crate::pubgrub::version::{PubGrubVersion, MIN_VERSION};

View file

@ -131,6 +131,7 @@ impl ReportFormatter<PubGrubPackage, Range<PubGrubVersion>> for PubGrubReportFor
} }
impl PubGrubReportFormatter<'_> { impl PubGrubReportFormatter<'_> {
/// Simplify a [`Range`] of versions using the available versions for a package.
fn simplify_set<'a>( fn simplify_set<'a>(
&self, &self,
set: &'a Range<PubGrubVersion>, set: &'a Range<PubGrubVersion>,
@ -142,20 +143,17 @@ impl PubGrubReportFormatter<'_> {
Cow::Owned(set.simplify(self.available_versions.get(package).into_iter().flatten())) 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 /// Generate the [`PubGrubHints`] for a derivation tree.
/// their requirements. ///
#[derive(Debug, Default)] /// The [`PubGrubHints`] help users resolve errors by providing additional context or modifying
pub(crate) struct PubGrubHints(FxHashSet<PubGrubHint>); /// their requirements.
pub(crate) fn hints(
impl PubGrubHints { &self,
/// Create a set of hints from a derivation tree.
pub(crate) fn from_derivation_tree(
derivation_tree: &DerivationTree<PubGrubPackage, Range<PubGrubVersion>>, derivation_tree: &DerivationTree<PubGrubPackage, Range<PubGrubVersion>>,
selector: &CandidateSelector, selector: &CandidateSelector,
) -> Self { ) -> FxHashSet<PubGrubHint> {
let mut hints = Self::default(); let mut hints = FxHashSet::default();
match derivation_tree { match derivation_tree {
DerivationTree::External(external) => match external { DerivationTree::External(external) => match external {
External::NoVersions(package, set) => { External::NoVersions(package, set) => {
@ -185,7 +183,7 @@ impl PubGrubHints {
if !allowed_prerelease { if !allowed_prerelease {
hints.insert(PubGrubHint::NoVersionsWithPreRelease { hints.insert(PubGrubHint::NoVersionsWithPreRelease {
package: package.clone(), package: package.clone(),
range: set.clone(), range: self.simplify_set(set, package).into_owned(),
}); });
} }
} }
@ -196,27 +194,12 @@ impl PubGrubHints {
External::FromDependencyOf(..) => {} External::FromDependencyOf(..) => {}
}, },
DerivationTree::Derived(derived) => { DerivationTree::Derived(derived) => {
hints.extend(Self::from_derivation_tree(&derived.cause1, selector)); hints.extend(self.hints(&derived.cause1, selector));
hints.extend(Self::from_derivation_tree(&derived.cause2, selector)); hints.extend(self.hints(&derived.cause2, selector));
} }
} }
hints hints
} }
/// Iterate over the hints in the set.
pub(crate) fn iter(&self) -> impl Iterator<Item = &PubGrubHint> {
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)] #[derive(Derivative, Debug, Clone)]