Use owned versions in `PythonRequirement`

This commit is contained in:
Zanie 2024-01-21 10:18:34 -06:00
parent 334dc1ea08
commit 83bda6621c
5 changed files with 26 additions and 36 deletions

View File

@ -130,14 +130,7 @@ pub struct NoSolutionError {
derivation_tree: DerivationTree<PubGrubPackage, Range<Version>>,
available_versions: FxHashMap<PubGrubPackage, Vec<Version>>,
selector: Option<CandidateSelector>,
python_requirement: Option<SolutionPythonRequirement>,
}
/// Derivative of [`PythonRequirement`] with owned data for error reporting.
#[derive(Debug, Clone)]
pub(crate) struct SolutionPythonRequirement {
pub(crate) installed: Version,
pub(crate) target: Version,
python_requirement: Option<PythonRequirement>,
}
impl std::error::Error for NoSolutionError {}
@ -219,10 +212,7 @@ impl NoSolutionError {
mut self,
python_requirement: &PythonRequirement,
) -> Self {
self.python_requirement = Some(SolutionPythonRequirement {
target: python_requirement.target().clone(),
installed: python_requirement.installed().clone(),
});
self.python_requirement = Some(python_requirement.clone());
self
}
}

View File

@ -12,8 +12,8 @@ use pubgrub::type_aliases::Map;
use rustc_hash::{FxHashMap, FxHashSet};
use crate::candidate_selector::CandidateSelector;
use crate::error::SolutionPythonRequirement;
use crate::prerelease_mode::PreReleaseStrategy;
use crate::python_requirement::PythonRequirement;
use super::PubGrubPackage;
@ -23,7 +23,7 @@ pub(crate) struct PubGrubReportFormatter<'a> {
pub(crate) available_versions: &'a FxHashMap<PubGrubPackage, Vec<Version>>,
/// The versions that were available for each package
pub(crate) python_requirement: Option<&'a SolutionPythonRequirement>,
pub(crate) python_requirement: Option<&'a PythonRequirement>,
}
impl ReportFormatter<PubGrubPackage, Range<Version>> for PubGrubReportFormatter<'_> {
@ -37,8 +37,8 @@ impl ReportFormatter<PubGrubPackage, Range<Version>> for PubGrubReportFormatter<
External::NoVersions(package, set) => {
if matches!(package, PubGrubPackage::Python(_)) {
if let Some(python) = self.python_requirement {
if python.target.release().iter().eq(python
.installed
if python.target().release().iter().eq(python
.installed()
.release()
.iter()
.take(2))
@ -50,28 +50,28 @@ impl ReportFormatter<PubGrubPackage, Range<Version>> for PubGrubReportFormatter<
// display instead.
return format!(
"the current {package} version ({}) does not satisfy {}",
python.target,
python.target(),
PackageRange::compatibility(package, set)
);
}
// Complex case, the target was provided and differs from the installed one
// Determine which Python version requirement was not met
if !set.contains(&python.target) {
if !set.contains(python.target()) {
return format!(
"the requested {package} version ({}) does not satisfy {}",
python.target,
python.target(),
PackageRange::compatibility(package, set)
);
}
// TODO(zanieb): Explain to the user why the installed version is relevant
// when they provided a target version; probably via a "hint"
debug_assert!(
!set.contains(&python.installed),
!set.contains(python.installed()),
"There should not be an incompatibility where the range is satisfied by both Python requirements"
);
return format!(
"the current {package} version ({}) does not satisfy {}",
python.installed,
python.installed(),
PackageRange::compatibility(package, set)
);
}

View File

@ -3,30 +3,30 @@ use pep508_rs::MarkerEnvironment;
use puffin_interpreter::Interpreter;
#[derive(Debug, Clone)]
pub struct PythonRequirement<'a> {
pub struct PythonRequirement {
/// The installed version of Python.
installed: &'a Version,
installed: Version,
/// The target version of Python; that is, the version of Python for which we are resolving
/// dependencies. This is typically the same as the installed version, but may be different
/// when specifying an alternate Python version for the resolution.
target: &'a Version,
target: Version,
}
impl<'a> PythonRequirement<'a> {
pub fn new(interpreter: &'a Interpreter, markers: &'a MarkerEnvironment) -> Self {
impl PythonRequirement {
pub fn new(interpreter: &Interpreter, markers: &MarkerEnvironment) -> Self {
Self {
installed: interpreter.version(),
target: &markers.python_version.version,
installed: interpreter.version().clone(),
target: markers.python_version.version.clone(),
}
}
/// Return the installed version of Python.
pub(crate) fn installed(&self) -> &'a Version {
self.installed
pub(crate) fn installed(&self) -> &Version {
&self.installed
}
/// Return the target version of Python.
pub(crate) fn target(&self) -> &'a Version {
self.target
pub(crate) fn target(&self) -> &Version {
&self.target
}
}

View File

@ -63,7 +63,7 @@ pub struct Resolver<'a, Provider: ResolverProvider> {
overrides: Overrides,
allowed_urls: AllowedUrls,
markers: &'a MarkerEnvironment,
python_requirement: PythonRequirement<'a>,
python_requirement: PythonRequirement,
selector: CandidateSelector,
index: &'a InMemoryIndex,
/// A map from [`PackageId`] to the `Requires-Python` version specifiers for that package.
@ -120,7 +120,7 @@ impl<'a, Provider: ResolverProvider> Resolver<'a, Provider> {
manifest: Manifest,
options: ResolutionOptions,
markers: &'a MarkerEnvironment,
python_requirement: PythonRequirement<'a>,
python_requirement: PythonRequirement,
index: &'a InMemoryIndex,
provider: Provider,
) -> Self {

View File

@ -52,7 +52,7 @@ pub struct DefaultResolverProvider<'a, Context: BuildContext + Send + Sync> {
/// These are the entries from `--find-links` that act as overrides for index responses.
flat_index: &'a FlatIndex,
tags: &'a Tags,
python_requirement: PythonRequirement<'a>,
python_requirement: PythonRequirement,
exclude_newer: Option<DateTime<Utc>>,
allowed_yanks: AllowedYanks,
no_binary: &'a NoBinary,
@ -66,7 +66,7 @@ impl<'a, Context: BuildContext + Send + Sync> DefaultResolverProvider<'a, Contex
fetcher: DistributionDatabase<'a, Context>,
flat_index: &'a FlatIndex,
tags: &'a Tags,
python_requirement: PythonRequirement<'a>,
python_requirement: PythonRequirement,
exclude_newer: Option<DateTime<Utc>>,
allowed_yanks: AllowedYanks,
no_binary: &'a NoBinary,