mirror of
https://github.com/astral-sh/uv.git
synced 2025-08-04 19:08:04 +00:00
Remove PubGrubVersion
(#924)
## Summary I'm running into some annoyances converting `&Version` to `&PubGrubVersion` (which is just a wrapper type around `Version`), and I realized... We don't even need `PubGrubVersion`? The reason we "need" it today is due to the orphan trait rule: `Version` is defined in `pep440_rs`, but we want to `impl pubgrub::version::Version for Version` in the resolver crate. Instead of introducing a new type here, which leads to a lot of awkwardness around conversion and API isolation, what if we instead just implement `pubgrub::version::Version` in `pep440_rs` via a feature? That way, we can just use `Version` everywhere without any confusion and conversion for the wrapper type.
This commit is contained in:
parent
8860a9c29e
commit
9a3f3d385c
20 changed files with 179 additions and 254 deletions
2
Cargo.lock
generated
2
Cargo.lock
generated
|
@ -2045,6 +2045,8 @@ name = "pep440_rs"
|
|||
version = "0.3.12"
|
||||
dependencies = [
|
||||
"indoc",
|
||||
"once_cell",
|
||||
"pubgrub",
|
||||
"pyo3",
|
||||
"serde",
|
||||
"tracing",
|
||||
|
|
|
@ -17,6 +17,8 @@ name = "pep440_rs"
|
|||
crate-type = ["rlib", "cdylib"]
|
||||
|
||||
[dependencies]
|
||||
once_cell = { workspace = true }
|
||||
pubgrub = { workspace = true, optional = true }
|
||||
pyo3 = { workspace = true, optional = true, features = ["extension-module", "abi3-py37"] }
|
||||
serde = { workspace = true, features = ["derive"], optional = true }
|
||||
tracing = { workspace = true, optional = true }
|
||||
|
@ -24,4 +26,4 @@ unicode-width = { workspace = true }
|
|||
unscanny = { workspace = true }
|
||||
|
||||
[dev-dependencies]
|
||||
indoc = "2.0.4"
|
||||
indoc = { version = "2.0.4" }
|
||||
|
|
|
@ -34,29 +34,26 @@
|
|||
//! the version matching needs to catch all sorts of special cases
|
||||
#![deny(missing_docs)]
|
||||
|
||||
#[cfg(feature = "pyo3")]
|
||||
pub use version::PyVersion;
|
||||
pub use {
|
||||
version::{
|
||||
LocalSegment, Operator, OperatorParseError, PreRelease, Version, VersionParseError,
|
||||
VersionPattern, VersionPatternParseError,
|
||||
VersionPattern, VersionPatternParseError, MIN_VERSION,
|
||||
},
|
||||
version_specifier::{
|
||||
parse_version_specifiers, VersionSpecifier, VersionSpecifiers, VersionSpecifiersParseError,
|
||||
},
|
||||
};
|
||||
|
||||
#[cfg(feature = "pyo3")]
|
||||
use pyo3::{pymodule, types::PyModule, PyResult, Python};
|
||||
#[cfg(feature = "pyo3")]
|
||||
pub use version::PyVersion;
|
||||
|
||||
mod version;
|
||||
mod version_specifier;
|
||||
|
||||
/// Python bindings shipped as `pep440_rs`
|
||||
#[cfg(feature = "pyo3")]
|
||||
#[pymodule]
|
||||
#[pyo3::pymodule]
|
||||
#[pyo3(name = "_pep440_rs")]
|
||||
pub fn python_module(_py: Python, module: &PyModule) -> PyResult<()> {
|
||||
pub fn python_module(_py: pyo3::Python, module: &pyo3::types::PyModule) -> pyo3::PyResult<()> {
|
||||
module.add_class::<PyVersion>()?;
|
||||
module.add_class::<Operator>()?;
|
||||
module.add_class::<VersionSpecifier>()?;
|
||||
|
|
|
@ -2194,6 +2194,29 @@ fn parse_u64(bytes: &[u8]) -> Result<u64, VersionParseError> {
|
|||
Ok(n)
|
||||
}
|
||||
|
||||
/// The minimum version that can be represented by a [`Version`].
|
||||
pub static MIN_VERSION: once_cell::sync::Lazy<Version> =
|
||||
once_cell::sync::Lazy::new(|| Version::from_str("0a0.dev0").unwrap());
|
||||
|
||||
#[cfg(feature = "pubgrub")]
|
||||
impl pubgrub::version::Version for Version {
|
||||
fn lowest() -> Self {
|
||||
MIN_VERSION.to_owned()
|
||||
}
|
||||
|
||||
fn bump(&self) -> Self {
|
||||
let mut next = self.clone();
|
||||
if let Some(dev) = next.dev() {
|
||||
next = next.with_dev(Some(dev + 1));
|
||||
} else if let Some(post) = next.post() {
|
||||
next = next.with_post(Some(post + 1));
|
||||
} else {
|
||||
next = next.with_post(Some(0)).with_dev(Some(0));
|
||||
}
|
||||
next
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use std::str::FromStr;
|
||||
|
|
|
@ -13,18 +13,10 @@ use pep440_rs::Version;
|
|||
use platform_tags::Tags;
|
||||
use puffin_normalize::PackageName;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct FlatIndex<T: Into<Version> + From<Version> + Ord>(
|
||||
pub BTreeMap<T, PrioritizedDistribution>,
|
||||
);
|
||||
#[derive(Debug, Clone, Default)]
|
||||
pub struct FlatIndex(pub BTreeMap<Version, PrioritizedDistribution>);
|
||||
|
||||
impl<T: Into<Version> + From<Version> + Ord> Default for FlatIndex<T> {
|
||||
fn default() -> Self {
|
||||
Self(BTreeMap::default())
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Into<Version> + From<Version> + Ord> FlatIndex<T> {
|
||||
impl FlatIndex {
|
||||
/// Collect all the files from `--find-links` into a override hashmap we can pass into version map creation.
|
||||
#[instrument(skip_all)]
|
||||
pub fn from_files(
|
||||
|
@ -44,7 +36,7 @@ impl<T: Into<Version> + From<Version> + Ord> FlatIndex<T> {
|
|||
}
|
||||
|
||||
fn add_file(
|
||||
version_map: &mut FlatIndex<T>,
|
||||
version_map: &mut FlatIndex,
|
||||
file: File,
|
||||
filename: DistFilename,
|
||||
tags: &Tags,
|
||||
|
@ -62,7 +54,7 @@ impl<T: Into<Version> + From<Version> + Ord> FlatIndex<T> {
|
|||
file,
|
||||
index,
|
||||
}));
|
||||
match version_map.0.entry(version.into()) {
|
||||
match version_map.0.entry(version) {
|
||||
Entry::Occupied(mut entry) => {
|
||||
entry.get_mut().insert_built(dist, None, None, priority);
|
||||
}
|
||||
|
@ -79,7 +71,7 @@ impl<T: Into<Version> + From<Version> + Ord> FlatIndex<T> {
|
|||
file,
|
||||
index,
|
||||
}));
|
||||
match version_map.0.entry(filename.version.clone().into()) {
|
||||
match version_map.0.entry(filename.version.clone()) {
|
||||
Entry::Occupied(mut entry) => {
|
||||
entry.get_mut().insert_source(dist, None, None);
|
||||
}
|
||||
|
@ -91,7 +83,7 @@ impl<T: Into<Version> + From<Version> + Ord> FlatIndex<T> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn iter(&self) -> impl Iterator<Item = (&T, &PrioritizedDistribution)> {
|
||||
pub fn iter(&self) -> impl Iterator<Item = (&Version, &PrioritizedDistribution)> {
|
||||
self.0.iter()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,7 +17,7 @@ cache-key = { path = "../cache-key" }
|
|||
distribution-filename = { path = "../distribution-filename", features = ["serde"] }
|
||||
distribution-types = { path = "../distribution-types" }
|
||||
install-wheel-rs = { path = "../install-wheel-rs" }
|
||||
pep440_rs = { path = "../pep440-rs" }
|
||||
pep440_rs = { path = "../pep440-rs", features = ["pubgrub"] }
|
||||
pep508_rs = { path = "../pep508-rs" }
|
||||
platform-host = { path = "../platform-host" }
|
||||
platform-tags = { path = "../platform-tags" }
|
||||
|
|
|
@ -3,12 +3,11 @@ use rustc_hash::FxHashMap;
|
|||
|
||||
use distribution_types::{Dist, DistributionMetadata, Name};
|
||||
use distribution_types::{DistRequiresPython, ResolvableDist};
|
||||
use pep440_rs::VersionSpecifiers;
|
||||
use pep440_rs::{Version, VersionSpecifiers};
|
||||
use pep508_rs::{Requirement, VersionOrUrl};
|
||||
use puffin_normalize::PackageName;
|
||||
|
||||
use crate::prerelease_mode::PreReleaseStrategy;
|
||||
use crate::pubgrub::PubGrubVersion;
|
||||
use crate::python_requirement::PythonRequirement;
|
||||
use crate::resolution_mode::ResolutionStrategy;
|
||||
use crate::version_map::VersionMap;
|
||||
|
@ -52,10 +51,10 @@ impl CandidateSelector {
|
|||
|
||||
/// A set of pinned packages that should be preserved during resolution, if possible.
|
||||
#[derive(Debug, Clone)]
|
||||
struct Preferences(FxHashMap<PackageName, PubGrubVersion>);
|
||||
struct Preferences(FxHashMap<PackageName, Version>);
|
||||
|
||||
impl Preferences {
|
||||
fn get(&self, package_name: &PackageName) -> Option<&PubGrubVersion> {
|
||||
fn get(&self, package_name: &PackageName) -> Option<&Version> {
|
||||
self.0.get(package_name)
|
||||
}
|
||||
}
|
||||
|
@ -74,8 +73,10 @@ impl From<&[Requirement]> for Preferences {
|
|||
let [version_specifier] = version_specifiers.as_ref() else {
|
||||
return None;
|
||||
};
|
||||
let version = PubGrubVersion::from(version_specifier.version().clone());
|
||||
Some((requirement.name.clone(), version))
|
||||
Some((
|
||||
requirement.name.clone(),
|
||||
version_specifier.version().clone(),
|
||||
))
|
||||
})
|
||||
.collect(),
|
||||
)
|
||||
|
@ -94,7 +95,7 @@ impl CandidateSelector {
|
|||
pub(crate) fn select<'a>(
|
||||
&'a self,
|
||||
package_name: &'a PackageName,
|
||||
range: &Range<PubGrubVersion>,
|
||||
range: &Range<Version>,
|
||||
version_map: &'a VersionMap,
|
||||
) -> Option<Candidate<'a>> {
|
||||
// If the package has a preference (e.g., an existing version from an existing lockfile),
|
||||
|
@ -161,15 +162,15 @@ impl CandidateSelector {
|
|||
/// Select the first-matching [`Candidate`] from a set of candidate versions and files,
|
||||
/// preferring wheels over source distributions.
|
||||
fn select_candidate<'a>(
|
||||
versions: impl Iterator<Item = (&'a PubGrubVersion, ResolvableDist<'a>)>,
|
||||
versions: impl Iterator<Item = (&'a Version, ResolvableDist<'a>)>,
|
||||
package_name: &'a PackageName,
|
||||
range: &Range<PubGrubVersion>,
|
||||
range: &Range<Version>,
|
||||
allow_prerelease: AllowPreRelease,
|
||||
) -> Option<Candidate<'a>> {
|
||||
#[derive(Debug)]
|
||||
enum PreReleaseCandidate<'a> {
|
||||
NotNecessary,
|
||||
IfNecessary(&'a PubGrubVersion, ResolvableDist<'a>),
|
||||
IfNecessary(&'a Version, ResolvableDist<'a>),
|
||||
}
|
||||
|
||||
let mut prerelease = None;
|
||||
|
@ -221,13 +222,13 @@ pub(crate) struct Candidate<'a> {
|
|||
/// The name of the package.
|
||||
name: &'a PackageName,
|
||||
/// The version of the package.
|
||||
version: &'a PubGrubVersion,
|
||||
version: &'a Version,
|
||||
/// The file to use for resolving and installing the package.
|
||||
dist: ResolvableDist<'a>,
|
||||
}
|
||||
|
||||
impl<'a> Candidate<'a> {
|
||||
fn new(name: &'a PackageName, version: &'a PubGrubVersion, dist: ResolvableDist<'a>) -> Self {
|
||||
fn new(name: &'a PackageName, version: &'a Version, dist: ResolvableDist<'a>) -> Self {
|
||||
Self {
|
||||
name,
|
||||
version,
|
||||
|
@ -241,7 +242,7 @@ impl<'a> Candidate<'a> {
|
|||
}
|
||||
|
||||
/// Return the version of the package.
|
||||
pub(crate) fn version(&self) -> &PubGrubVersion {
|
||||
pub(crate) fn version(&self) -> &Version {
|
||||
self.version
|
||||
}
|
||||
|
||||
|
@ -299,6 +300,6 @@ impl Name for Candidate<'_> {
|
|||
|
||||
impl DistributionMetadata for Candidate<'_> {
|
||||
fn version_or_url(&self) -> distribution_types::VersionOrUrl {
|
||||
distribution_types::VersionOrUrl::Version(self.version.into())
|
||||
distribution_types::VersionOrUrl::Version(self.version)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,13 +8,14 @@ use thiserror::Error;
|
|||
use url::Url;
|
||||
|
||||
use distribution_types::{BuiltDist, PathBuiltDist, PathSourceDist, SourceDist};
|
||||
use pep440_rs::Version;
|
||||
use pep508_rs::Requirement;
|
||||
use puffin_distribution::DistributionDatabaseError;
|
||||
use puffin_normalize::PackageName;
|
||||
use puffin_traits::OnceMap;
|
||||
|
||||
use crate::candidate_selector::CandidateSelector;
|
||||
use crate::pubgrub::{PubGrubPackage, PubGrubPython, PubGrubReportFormatter, PubGrubVersion};
|
||||
use crate::pubgrub::{PubGrubPackage, PubGrubPython, PubGrubReportFormatter};
|
||||
use crate::python_requirement::PythonRequirement;
|
||||
use crate::version_map::VersionMap;
|
||||
|
||||
|
@ -76,7 +77,7 @@ pub enum ResolveError {
|
|||
/// Package whose dependencies we want.
|
||||
package: Box<PubGrubPackage>,
|
||||
/// Version of the package for which we want the dependencies.
|
||||
version: Box<PubGrubVersion>,
|
||||
version: Box<Version>,
|
||||
},
|
||||
|
||||
/// Something unexpected happened.
|
||||
|
@ -90,11 +91,11 @@ impl<T> From<futures::channel::mpsc::TrySendError<T>> for ResolveError {
|
|||
}
|
||||
}
|
||||
|
||||
impl From<pubgrub::error::PubGrubError<PubGrubPackage, Range<PubGrubVersion>, Infallible>>
|
||||
impl From<pubgrub::error::PubGrubError<PubGrubPackage, Range<Version>, Infallible>>
|
||||
for ResolveError
|
||||
{
|
||||
fn from(
|
||||
value: pubgrub::error::PubGrubError<PubGrubPackage, Range<PubGrubVersion>, Infallible>,
|
||||
value: pubgrub::error::PubGrubError<PubGrubPackage, Range<Version>, Infallible>,
|
||||
) -> Self {
|
||||
match value {
|
||||
// These are all never type variant that can never match, but never is experimental
|
||||
|
@ -124,8 +125,8 @@ impl From<pubgrub::error::PubGrubError<PubGrubPackage, Range<PubGrubVersion>, In
|
|||
/// A wrapper around [`pubgrub::error::PubGrubError::NoSolution`] that displays a resolution failure report.
|
||||
#[derive(Debug)]
|
||||
pub struct NoSolutionError {
|
||||
derivation_tree: DerivationTree<PubGrubPackage, Range<PubGrubVersion>>,
|
||||
available_versions: FxHashMap<PubGrubPackage, Vec<PubGrubVersion>>,
|
||||
derivation_tree: DerivationTree<PubGrubPackage, Range<Version>>,
|
||||
available_versions: FxHashMap<PubGrubPackage, Vec<Version>>,
|
||||
selector: Option<CandidateSelector>,
|
||||
}
|
||||
|
||||
|
@ -169,14 +170,12 @@ impl NoSolutionError {
|
|||
PubGrubPackage::Python(PubGrubPython::Installed) => {
|
||||
available_versions.insert(
|
||||
package.clone(),
|
||||
vec![PubGrubVersion::from(python_requirement.installed().clone())],
|
||||
vec![python_requirement.installed().clone()],
|
||||
);
|
||||
}
|
||||
PubGrubPackage::Python(PubGrubPython::Target) => {
|
||||
available_versions.insert(
|
||||
package.clone(),
|
||||
vec![PubGrubVersion::from(python_requirement.target().clone())],
|
||||
);
|
||||
available_versions
|
||||
.insert(package.clone(), vec![python_requirement.target().clone()]);
|
||||
}
|
||||
PubGrubPackage::Package(name, ..) => {
|
||||
if let Some(entry) = package_versions.get(name) {
|
||||
|
|
|
@ -8,7 +8,6 @@ use rustc_hash::FxHashMap;
|
|||
|
||||
use distribution_filename::DistFilename;
|
||||
use distribution_types::{Dist, IndexUrl, Resolution};
|
||||
use pep440_rs::Version;
|
||||
use pep508_rs::{Requirement, VersionOrUrl};
|
||||
use platform_tags::Tags;
|
||||
use puffin_client::{FlatIndex, RegistryClient, SimpleMetadata};
|
||||
|
@ -22,7 +21,7 @@ pub struct DistFinder<'a> {
|
|||
client: &'a RegistryClient,
|
||||
reporter: Option<Box<dyn Reporter>>,
|
||||
interpreter: &'a Interpreter,
|
||||
flat_index: &'a FxHashMap<PackageName, FlatIndex<Version>>,
|
||||
flat_index: &'a FxHashMap<PackageName, FlatIndex>,
|
||||
}
|
||||
|
||||
impl<'a> DistFinder<'a> {
|
||||
|
@ -31,7 +30,7 @@ impl<'a> DistFinder<'a> {
|
|||
tags: &'a Tags,
|
||||
client: &'a RegistryClient,
|
||||
interpreter: &'a Interpreter,
|
||||
flat_index: &'a FxHashMap<PackageName, FlatIndex<Version>>,
|
||||
flat_index: &'a FxHashMap<PackageName, FlatIndex>,
|
||||
) -> Self {
|
||||
Self {
|
||||
tags,
|
||||
|
@ -57,7 +56,7 @@ impl<'a> DistFinder<'a> {
|
|||
async fn resolve_requirement(
|
||||
&self,
|
||||
requirement: &Requirement,
|
||||
flat_index: Option<&FlatIndex<Version>>,
|
||||
flat_index: Option<&FlatIndex>,
|
||||
) -> Result<(PackageName, Dist), ResolveError> {
|
||||
match requirement.version_or_url.as_ref() {
|
||||
None | Some(VersionOrUrl::VersionSpecifier(_)) => {
|
||||
|
@ -119,7 +118,7 @@ impl<'a> DistFinder<'a> {
|
|||
requirement: &Requirement,
|
||||
metadata: SimpleMetadata,
|
||||
index: &IndexUrl,
|
||||
flat_index: Option<&FlatIndex<Version>>,
|
||||
flat_index: Option<&FlatIndex>,
|
||||
) -> Option<Dist> {
|
||||
// Prioritize the flat index by initializing the "best" matches with its entries.
|
||||
let matching_override = if let Some(flat_index) = flat_index {
|
||||
|
|
|
@ -16,7 +16,7 @@ impl FilePins {
|
|||
/// Pin a candidate package.
|
||||
pub(crate) fn insert(&mut self, candidate: &Candidate) {
|
||||
self.0.entry(candidate.name().clone()).or_default().insert(
|
||||
candidate.version().clone().into(),
|
||||
candidate.version().clone(),
|
||||
candidate.install().dist.clone(),
|
||||
);
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
use itertools::Itertools;
|
||||
use pep440_rs::Version;
|
||||
use pubgrub::range::Range;
|
||||
use pubgrub::type_aliases::DependencyConstraints;
|
||||
use tracing::warn;
|
||||
|
@ -8,11 +9,11 @@ use puffin_normalize::{ExtraName, PackageName};
|
|||
|
||||
use crate::overrides::Overrides;
|
||||
use crate::pubgrub::specifier::PubGrubSpecifier;
|
||||
use crate::pubgrub::{PubGrubPackage, PubGrubVersion};
|
||||
use crate::pubgrub::PubGrubPackage;
|
||||
use crate::ResolveError;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct PubGrubDependencies(DependencyConstraints<PubGrubPackage, Range<PubGrubVersion>>);
|
||||
pub struct PubGrubDependencies(DependencyConstraints<PubGrubPackage, Range<Version>>);
|
||||
|
||||
impl PubGrubDependencies {
|
||||
/// Generate a set of `PubGrub` dependencies from a set of requirements.
|
||||
|
@ -24,8 +25,7 @@ impl PubGrubDependencies {
|
|||
source: Option<&PackageName>,
|
||||
env: &MarkerEnvironment,
|
||||
) -> Result<Self, ResolveError> {
|
||||
let mut dependencies =
|
||||
DependencyConstraints::<PubGrubPackage, Range<PubGrubVersion>>::default();
|
||||
let mut dependencies = DependencyConstraints::<PubGrubPackage, Range<Version>>::default();
|
||||
|
||||
// Iterate over all declared requirements.
|
||||
for requirement in overrides.apply(requirements) {
|
||||
|
@ -126,23 +126,23 @@ impl PubGrubDependencies {
|
|||
Ok(Self(dependencies))
|
||||
}
|
||||
|
||||
/// Insert a [`PubGrubPackage`] and [`PubGrubVersion`] range into the set of dependencies.
|
||||
/// Insert a [`PubGrubPackage`] and [`Version`] range into the set of dependencies.
|
||||
pub(crate) fn insert(
|
||||
&mut self,
|
||||
package: PubGrubPackage,
|
||||
version: Range<PubGrubVersion>,
|
||||
) -> Option<Range<PubGrubVersion>> {
|
||||
version: Range<Version>,
|
||||
) -> Option<Range<Version>> {
|
||||
self.0.insert(package, version)
|
||||
}
|
||||
|
||||
/// Iterate over the dependencies.
|
||||
pub(crate) fn iter(&self) -> impl Iterator<Item = (&PubGrubPackage, &Range<PubGrubVersion>)> {
|
||||
pub(crate) fn iter(&self) -> impl Iterator<Item = (&PubGrubPackage, &Range<Version>)> {
|
||||
self.0.iter()
|
||||
}
|
||||
}
|
||||
|
||||
/// Convert a [`PubGrubDependencies`] to a [`DependencyConstraints`].
|
||||
impl From<PubGrubDependencies> for DependencyConstraints<PubGrubPackage, Range<PubGrubVersion>> {
|
||||
impl From<PubGrubDependencies> for DependencyConstraints<PubGrubPackage, Range<Version>> {
|
||||
fn from(dependencies: PubGrubDependencies) -> Self {
|
||||
dependencies.0
|
||||
}
|
||||
|
@ -152,7 +152,7 @@ impl From<PubGrubDependencies> for DependencyConstraints<PubGrubPackage, Range<P
|
|||
fn to_pubgrub(
|
||||
requirement: &Requirement,
|
||||
extra: Option<ExtraName>,
|
||||
) -> Result<(PubGrubPackage, Range<PubGrubVersion>), ResolveError> {
|
||||
) -> Result<(PubGrubPackage, Range<Version>), ResolveError> {
|
||||
match requirement.version_or_url.as_ref() {
|
||||
// The requirement has no specifier (e.g., `flask`).
|
||||
None => Ok((
|
||||
|
@ -180,12 +180,12 @@ fn to_pubgrub(
|
|||
}
|
||||
}
|
||||
|
||||
/// Merge two [`PubGrubVersion`] ranges.
|
||||
/// Merge two [`Version`] ranges.
|
||||
fn merge_versions(
|
||||
package: &PubGrubPackage,
|
||||
left: &Range<PubGrubVersion>,
|
||||
right: &Range<PubGrubVersion>,
|
||||
) -> Result<Range<PubGrubVersion>, ResolveError> {
|
||||
left: &Range<Version>,
|
||||
right: &Range<Version>,
|
||||
) -> Result<Range<Version>, ResolveError> {
|
||||
let result = left.intersection(right);
|
||||
if result.is_empty() {
|
||||
Err(ResolveError::ConflictingVersions(
|
||||
|
|
|
@ -1,17 +1,16 @@
|
|||
use distribution_types::{DistributionMetadata, Name, VersionOrUrl};
|
||||
use pep440_rs::Version;
|
||||
use pep508_rs::VerbatimUrl;
|
||||
use puffin_normalize::PackageName;
|
||||
|
||||
use crate::pubgrub::PubGrubVersion;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub(crate) enum PubGrubDistribution<'a> {
|
||||
Registry(&'a PackageName, &'a PubGrubVersion),
|
||||
Registry(&'a PackageName, &'a Version),
|
||||
Url(&'a PackageName, &'a VerbatimUrl),
|
||||
}
|
||||
|
||||
impl<'a> PubGrubDistribution<'a> {
|
||||
pub(crate) fn from_registry(name: &'a PackageName, version: &'a PubGrubVersion) -> Self {
|
||||
pub(crate) fn from_registry(name: &'a PackageName, version: &'a Version) -> Self {
|
||||
Self::Registry(name, version)
|
||||
}
|
||||
|
||||
|
@ -32,7 +31,7 @@ impl Name for PubGrubDistribution<'_> {
|
|||
impl DistributionMetadata for PubGrubDistribution<'_> {
|
||||
fn version_or_url(&self) -> VersionOrUrl {
|
||||
match self {
|
||||
Self::Registry(_, version) => VersionOrUrl::Version((*version).into()),
|
||||
Self::Registry(_, version) => VersionOrUrl::Version(version),
|
||||
Self::Url(_, url) => VersionOrUrl::Url(url),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,7 +4,6 @@ pub(crate) use crate::pubgrub::package::{PubGrubPackage, PubGrubPython};
|
|||
pub(crate) use crate::pubgrub::priority::{PubGrubPriorities, PubGrubPriority};
|
||||
pub(crate) use crate::pubgrub::report::PubGrubReportFormatter;
|
||||
pub(crate) use crate::pubgrub::specifier::PubGrubSpecifier;
|
||||
pub(crate) use crate::pubgrub::version::{PubGrubVersion, MIN_VERSION};
|
||||
|
||||
mod dependencies;
|
||||
mod distribution;
|
||||
|
@ -12,4 +11,3 @@ mod package;
|
|||
mod priority;
|
||||
mod report;
|
||||
mod specifier;
|
||||
mod version;
|
||||
|
|
|
@ -4,6 +4,7 @@ use std::ops::Bound;
|
|||
|
||||
use derivative::Derivative;
|
||||
use owo_colors::OwoColorize;
|
||||
use pep440_rs::Version;
|
||||
use pubgrub::range::Range;
|
||||
use pubgrub::report::{DerivationTree, Derived, External, ReportFormatter};
|
||||
use pubgrub::term::Term;
|
||||
|
@ -13,21 +14,18 @@ use rustc_hash::{FxHashMap, FxHashSet};
|
|||
use crate::candidate_selector::CandidateSelector;
|
||||
use crate::prerelease_mode::PreReleaseStrategy;
|
||||
|
||||
use super::{PubGrubPackage, PubGrubVersion};
|
||||
use super::PubGrubPackage;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub(crate) struct PubGrubReportFormatter<'a> {
|
||||
/// The versions that were available for each package
|
||||
pub(crate) available_versions: &'a FxHashMap<PubGrubPackage, Vec<PubGrubVersion>>,
|
||||
pub(crate) available_versions: &'a FxHashMap<PubGrubPackage, Vec<Version>>,
|
||||
}
|
||||
|
||||
impl ReportFormatter<PubGrubPackage, Range<PubGrubVersion>> for PubGrubReportFormatter<'_> {
|
||||
impl ReportFormatter<PubGrubPackage, Range<Version>> for PubGrubReportFormatter<'_> {
|
||||
type Output = String;
|
||||
|
||||
fn format_external(
|
||||
&self,
|
||||
external: &External<PubGrubPackage, Range<PubGrubVersion>>,
|
||||
) -> Self::Output {
|
||||
fn format_external(&self, external: &External<PubGrubPackage, Range<Version>>) -> Self::Output {
|
||||
match external {
|
||||
External::NotRoot(package, version) => {
|
||||
format!("we are solving dependencies of {package} {version}")
|
||||
|
@ -93,7 +91,7 @@ impl ReportFormatter<PubGrubPackage, Range<PubGrubVersion>> for PubGrubReportFor
|
|||
}
|
||||
|
||||
/// Try to print terms of an incompatibility in a human-readable way.
|
||||
fn format_terms(&self, terms: &Map<PubGrubPackage, Term<Range<PubGrubVersion>>>) -> String {
|
||||
fn format_terms(&self, terms: &Map<PubGrubPackage, Term<Range<Version>>>) -> String {
|
||||
let terms_vec: Vec<_> = terms.iter().collect();
|
||||
match terms_vec.as_slice() {
|
||||
[] | [(PubGrubPackage::Root(_), _)] => "the requirements are unsatisfiable".into(),
|
||||
|
@ -154,9 +152,9 @@ impl ReportFormatter<PubGrubPackage, Range<PubGrubVersion>> for PubGrubReportFor
|
|||
/// Simplest case, we just combine two external incompatibilities.
|
||||
fn explain_both_external(
|
||||
&self,
|
||||
external1: &External<PubGrubPackage, Range<PubGrubVersion>>,
|
||||
external2: &External<PubGrubPackage, Range<PubGrubVersion>>,
|
||||
current_terms: &Map<PubGrubPackage, Term<Range<PubGrubVersion>>>,
|
||||
external1: &External<PubGrubPackage, Range<Version>>,
|
||||
external2: &External<PubGrubPackage, Range<Version>>,
|
||||
current_terms: &Map<PubGrubPackage, Term<Range<Version>>>,
|
||||
) -> String {
|
||||
let external1 = self.format_external(external1);
|
||||
let external2 = self.format_external(external2);
|
||||
|
@ -174,10 +172,10 @@ impl ReportFormatter<PubGrubPackage, Range<PubGrubVersion>> for PubGrubReportFor
|
|||
fn explain_both_ref(
|
||||
&self,
|
||||
ref_id1: usize,
|
||||
derived1: &Derived<PubGrubPackage, Range<PubGrubVersion>>,
|
||||
derived1: &Derived<PubGrubPackage, Range<Version>>,
|
||||
ref_id2: usize,
|
||||
derived2: &Derived<PubGrubPackage, Range<PubGrubVersion>>,
|
||||
current_terms: &Map<PubGrubPackage, Term<Range<PubGrubVersion>>>,
|
||||
derived2: &Derived<PubGrubPackage, Range<Version>>,
|
||||
current_terms: &Map<PubGrubPackage, Term<Range<Version>>>,
|
||||
) -> String {
|
||||
// TODO: order should be chosen to make it more logical.
|
||||
|
||||
|
@ -201,9 +199,9 @@ impl ReportFormatter<PubGrubPackage, Range<PubGrubVersion>> for PubGrubReportFor
|
|||
fn explain_ref_and_external(
|
||||
&self,
|
||||
ref_id: usize,
|
||||
derived: &Derived<PubGrubPackage, Range<PubGrubVersion>>,
|
||||
external: &External<PubGrubPackage, Range<PubGrubVersion>>,
|
||||
current_terms: &Map<PubGrubPackage, Term<Range<PubGrubVersion>>>,
|
||||
derived: &Derived<PubGrubPackage, Range<Version>>,
|
||||
external: &External<PubGrubPackage, Range<Version>>,
|
||||
current_terms: &Map<PubGrubPackage, Term<Range<Version>>>,
|
||||
) -> String {
|
||||
// TODO: order should be chosen to make it more logical.
|
||||
|
||||
|
@ -223,8 +221,8 @@ impl ReportFormatter<PubGrubPackage, Range<PubGrubVersion>> for PubGrubReportFor
|
|||
/// Add an external cause to the chain of explanations.
|
||||
fn and_explain_external(
|
||||
&self,
|
||||
external: &External<PubGrubPackage, Range<PubGrubVersion>>,
|
||||
current_terms: &Map<PubGrubPackage, Term<Range<PubGrubVersion>>>,
|
||||
external: &External<PubGrubPackage, Range<Version>>,
|
||||
current_terms: &Map<PubGrubPackage, Term<Range<Version>>>,
|
||||
) -> String {
|
||||
let external = self.format_external(external);
|
||||
let terms = self.format_terms(current_terms);
|
||||
|
@ -240,8 +238,8 @@ impl ReportFormatter<PubGrubPackage, Range<PubGrubVersion>> for PubGrubReportFor
|
|||
fn and_explain_ref(
|
||||
&self,
|
||||
ref_id: usize,
|
||||
derived: &Derived<PubGrubPackage, Range<PubGrubVersion>>,
|
||||
current_terms: &Map<PubGrubPackage, Term<Range<PubGrubVersion>>>,
|
||||
derived: &Derived<PubGrubPackage, Range<Version>>,
|
||||
current_terms: &Map<PubGrubPackage, Term<Range<Version>>>,
|
||||
) -> String {
|
||||
let derived = self.format_terms(&derived.terms);
|
||||
let current = self.format_terms(current_terms);
|
||||
|
@ -257,9 +255,9 @@ impl ReportFormatter<PubGrubPackage, Range<PubGrubVersion>> for PubGrubReportFor
|
|||
/// Add an already explained incompat to the chain of explanations.
|
||||
fn and_explain_prior_and_external(
|
||||
&self,
|
||||
prior_external: &External<PubGrubPackage, Range<PubGrubVersion>>,
|
||||
external: &External<PubGrubPackage, Range<PubGrubVersion>>,
|
||||
current_terms: &Map<PubGrubPackage, Term<Range<PubGrubVersion>>>,
|
||||
prior_external: &External<PubGrubPackage, Range<Version>>,
|
||||
external: &External<PubGrubPackage, Range<Version>>,
|
||||
current_terms: &Map<PubGrubPackage, Term<Range<Version>>>,
|
||||
) -> String {
|
||||
let prior_external = self.format_external(prior_external);
|
||||
let external = self.format_external(external);
|
||||
|
@ -278,9 +276,9 @@ impl PubGrubReportFormatter<'_> {
|
|||
/// Simplify a [`Range`] of versions using the available versions for a package.
|
||||
fn simplify_set<'a>(
|
||||
&self,
|
||||
set: &'a Range<PubGrubVersion>,
|
||||
set: &'a Range<Version>,
|
||||
package: &PubGrubPackage,
|
||||
) -> Cow<'a, Range<PubGrubVersion>> {
|
||||
) -> Cow<'a, Range<Version>> {
|
||||
if set == &Range::full() {
|
||||
Cow::Borrowed(set)
|
||||
} else {
|
||||
|
@ -294,7 +292,7 @@ impl PubGrubReportFormatter<'_> {
|
|||
/// their requirements.
|
||||
pub(crate) fn hints(
|
||||
&self,
|
||||
derivation_tree: &DerivationTree<PubGrubPackage, Range<PubGrubVersion>>,
|
||||
derivation_tree: &DerivationTree<PubGrubPackage, Range<Version>>,
|
||||
selector: &CandidateSelector,
|
||||
) -> FxHashSet<PubGrubHint> {
|
||||
/// Returns `true` if pre-releases were allowed for a package.
|
||||
|
@ -324,7 +322,7 @@ impl PubGrubReportFormatter<'_> {
|
|||
match derivation_tree {
|
||||
DerivationTree::External(external) => match external {
|
||||
External::NoVersions(package, set) => {
|
||||
if set.bounds().any(PubGrubVersion::any_prerelease) {
|
||||
if set.bounds().any(Version::any_prerelease) {
|
||||
// A pre-release marker appeared in the version requirements.
|
||||
if !allowed_prerelease(package, selector) {
|
||||
hints.insert(PubGrubHint::PreReleaseRequested {
|
||||
|
@ -373,14 +371,14 @@ pub(crate) enum PubGrubHint {
|
|||
PreReleaseAvailable {
|
||||
package: PubGrubPackage,
|
||||
#[derivative(PartialEq = "ignore", Hash = "ignore")]
|
||||
version: PubGrubVersion,
|
||||
version: Version,
|
||||
},
|
||||
/// A requirement included a pre-release marker, but pre-releases weren't enabled for that
|
||||
/// package.
|
||||
PreReleaseRequested {
|
||||
package: PubGrubPackage,
|
||||
#[derivative(PartialEq = "ignore", Hash = "ignore")]
|
||||
range: Range<PubGrubVersion>,
|
||||
range: Range<Version>,
|
||||
},
|
||||
}
|
||||
|
||||
|
@ -414,7 +412,7 @@ impl std::fmt::Display for PubGrubHint {
|
|||
/// A [`Term`] and [`PubGrubPackage`] combination for display.
|
||||
struct PackageTerm<'a> {
|
||||
package: &'a PubGrubPackage,
|
||||
term: &'a Term<Range<PubGrubVersion>>,
|
||||
term: &'a Term<Range<Version>>,
|
||||
}
|
||||
|
||||
impl std::fmt::Display for PackageTerm<'_> {
|
||||
|
@ -434,10 +432,7 @@ impl std::fmt::Display for PackageTerm<'_> {
|
|||
}
|
||||
|
||||
impl PackageTerm<'_> {
|
||||
fn new<'a>(
|
||||
package: &'a PubGrubPackage,
|
||||
term: &'a Term<Range<PubGrubVersion>>,
|
||||
) -> PackageTerm<'a> {
|
||||
fn new<'a>(package: &'a PubGrubPackage, term: &'a Term<Range<Version>>) -> PackageTerm<'a> {
|
||||
PackageTerm { package, term }
|
||||
}
|
||||
}
|
||||
|
@ -453,7 +448,7 @@ enum PackageRangeKind {
|
|||
#[derive(Debug)]
|
||||
struct PackageRange<'a> {
|
||||
package: &'a PubGrubPackage,
|
||||
range: &'a Range<PubGrubVersion>,
|
||||
range: &'a Range<Version>,
|
||||
kind: PackageRangeKind,
|
||||
}
|
||||
|
||||
|
@ -506,7 +501,7 @@ impl std::fmt::Display for PackageRange<'_> {
|
|||
impl PackageRange<'_> {
|
||||
fn compatibility<'a>(
|
||||
package: &'a PubGrubPackage,
|
||||
range: &'a Range<PubGrubVersion>,
|
||||
range: &'a Range<Version>,
|
||||
) -> PackageRange<'a> {
|
||||
PackageRange {
|
||||
package,
|
||||
|
@ -515,10 +510,7 @@ impl PackageRange<'_> {
|
|||
}
|
||||
}
|
||||
|
||||
fn dependency<'a>(
|
||||
package: &'a PubGrubPackage,
|
||||
range: &'a Range<PubGrubVersion>,
|
||||
) -> PackageRange<'a> {
|
||||
fn dependency<'a>(package: &'a PubGrubPackage, range: &'a Range<Version>) -> PackageRange<'a> {
|
||||
PackageRange {
|
||||
package,
|
||||
range,
|
||||
|
|
|
@ -1,16 +1,15 @@
|
|||
use anyhow::Result;
|
||||
use pubgrub::range::Range;
|
||||
|
||||
use pep440_rs::{Operator, VersionSpecifier};
|
||||
use pep440_rs::{Operator, Version, VersionSpecifier};
|
||||
|
||||
use crate::pubgrub::version::PubGrubVersion;
|
||||
use crate::ResolveError;
|
||||
|
||||
/// A range of versions that can be used to satisfy a requirement.
|
||||
#[derive(Debug)]
|
||||
pub(crate) struct PubGrubSpecifier(Range<PubGrubVersion>);
|
||||
pub(crate) struct PubGrubSpecifier(Range<Version>);
|
||||
|
||||
impl From<PubGrubSpecifier> for Range<PubGrubVersion> {
|
||||
impl From<PubGrubSpecifier> for Range<Version> {
|
||||
/// Convert a `PubGrub` specifier to a range of versions.
|
||||
fn from(specifier: PubGrubSpecifier) -> Self {
|
||||
specifier.0
|
||||
|
@ -24,45 +23,43 @@ impl TryFrom<&VersionSpecifier> for PubGrubSpecifier {
|
|||
fn try_from(specifier: &VersionSpecifier) -> Result<Self, ResolveError> {
|
||||
let ranges = match specifier.operator() {
|
||||
Operator::Equal => {
|
||||
let version = PubGrubVersion::from(specifier.version().clone());
|
||||
let version = specifier.version().clone();
|
||||
Range::singleton(version)
|
||||
}
|
||||
Operator::ExactEqual => {
|
||||
let version = PubGrubVersion::from(specifier.version().clone());
|
||||
let version = specifier.version().clone();
|
||||
Range::singleton(version)
|
||||
}
|
||||
Operator::NotEqual => {
|
||||
let version = PubGrubVersion::from(specifier.version().clone());
|
||||
let version = specifier.version().clone();
|
||||
Range::singleton(version).complement()
|
||||
}
|
||||
Operator::TildeEqual => {
|
||||
let [rest @ .., last, _] = specifier.version().release() else {
|
||||
return Err(ResolveError::InvalidTildeEquals(specifier.clone()));
|
||||
};
|
||||
let upper = PubGrubVersion::from(
|
||||
pep440_rs::Version::new(rest.iter().chain([&(last + 1)]))
|
||||
.with_epoch(specifier.version().epoch())
|
||||
.with_dev(Some(0)),
|
||||
);
|
||||
let version = PubGrubVersion::from(specifier.version().clone());
|
||||
let upper = pep440_rs::Version::new(rest.iter().chain([&(last + 1)]))
|
||||
.with_epoch(specifier.version().epoch())
|
||||
.with_dev(Some(0));
|
||||
let version = specifier.version().clone();
|
||||
Range::from_range_bounds(version..upper)
|
||||
}
|
||||
Operator::LessThan => {
|
||||
let version = PubGrubVersion::from(specifier.version().clone());
|
||||
let version = specifier.version().clone();
|
||||
Range::strictly_lower_than(version)
|
||||
}
|
||||
Operator::LessThanEqual => {
|
||||
let version = PubGrubVersion::from(specifier.version().clone());
|
||||
let version = specifier.version().clone();
|
||||
Range::lower_than(version)
|
||||
}
|
||||
Operator::GreaterThan => {
|
||||
// Per PEP 440: "The exclusive ordered comparison >V MUST NOT allow a post-release of
|
||||
// the given version unless V itself is a post release."
|
||||
let version = PubGrubVersion::from(specifier.version().clone());
|
||||
let version = specifier.version().clone();
|
||||
Range::strictly_higher_than(version)
|
||||
}
|
||||
Operator::GreaterThanEqual => {
|
||||
let version = PubGrubVersion::from(specifier.version().clone());
|
||||
let version = specifier.version().clone();
|
||||
Range::higher_than(version)
|
||||
}
|
||||
Operator::EqualStar => {
|
||||
|
@ -81,7 +78,7 @@ impl TryFrom<&VersionSpecifier> for PubGrubSpecifier {
|
|||
*release.last_mut().unwrap() += 1;
|
||||
high = high.with_release(release);
|
||||
}
|
||||
Range::from_range_bounds(PubGrubVersion::from(low)..PubGrubVersion::from(high))
|
||||
Range::from_range_bounds(low..high)
|
||||
}
|
||||
Operator::NotEqualStar => {
|
||||
let low = specifier.version().clone().with_dev(Some(0));
|
||||
|
@ -99,8 +96,7 @@ impl TryFrom<&VersionSpecifier> for PubGrubSpecifier {
|
|||
*release.last_mut().unwrap() += 1;
|
||||
high = high.with_release(release);
|
||||
}
|
||||
Range::from_range_bounds(PubGrubVersion::from(low)..PubGrubVersion::from(high))
|
||||
.complement()
|
||||
Range::from_range_bounds(low..high).complement()
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -1,69 +0,0 @@
|
|||
use std::str::FromStr;
|
||||
|
||||
use once_cell::sync::Lazy;
|
||||
|
||||
/// A PubGrub-compatible wrapper around a PEP 440 version.
|
||||
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||
pub struct PubGrubVersion(pep440_rs::Version);
|
||||
|
||||
impl PubGrubVersion {
|
||||
/// Returns the smallest PEP 440 version that is larger than `self`.
|
||||
pub fn next(&self) -> PubGrubVersion {
|
||||
let mut next = self.clone();
|
||||
if let Some(dev) = next.0.dev() {
|
||||
next.0 = next.0.with_dev(Some(dev + 1));
|
||||
} else if let Some(post) = next.0.post() {
|
||||
next.0 = next.0.with_post(Some(post + 1));
|
||||
} else {
|
||||
next.0 = next.0.with_post(Some(0)).with_dev(Some(0));
|
||||
}
|
||||
next
|
||||
}
|
||||
|
||||
pub fn any_prerelease(&self) -> bool {
|
||||
self.0.any_prerelease()
|
||||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Display for PubGrubVersion {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
self.0.fmt(f)
|
||||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Debug for PubGrubVersion {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
self.0.fmt(f)
|
||||
}
|
||||
}
|
||||
|
||||
impl pubgrub::version::Version for PubGrubVersion {
|
||||
fn lowest() -> Self {
|
||||
MIN_VERSION.to_owned()
|
||||
}
|
||||
|
||||
fn bump(&self) -> Self {
|
||||
self.next()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> From<&'a PubGrubVersion> for &'a pep440_rs::Version {
|
||||
fn from(version: &'a PubGrubVersion) -> Self {
|
||||
&version.0
|
||||
}
|
||||
}
|
||||
|
||||
impl From<pep440_rs::Version> for PubGrubVersion {
|
||||
fn from(version: pep440_rs::Version) -> Self {
|
||||
Self(version)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<PubGrubVersion> for pep440_rs::Version {
|
||||
fn from(version: PubGrubVersion) -> Self {
|
||||
version.0
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) static MIN_VERSION: Lazy<PubGrubVersion> =
|
||||
Lazy::new(|| PubGrubVersion::from(pep440_rs::Version::from_str("0a0.dev0").unwrap()));
|
|
@ -19,7 +19,7 @@ use puffin_traits::OnceMap;
|
|||
use pypi_types::{Hashes, Metadata21};
|
||||
|
||||
use crate::pins::FilePins;
|
||||
use crate::pubgrub::{PubGrubDistribution, PubGrubPackage, PubGrubPriority, PubGrubVersion};
|
||||
use crate::pubgrub::{PubGrubDistribution, PubGrubPackage, PubGrubPriority};
|
||||
use crate::version_map::VersionMap;
|
||||
use crate::ResolveError;
|
||||
|
||||
|
@ -28,7 +28,7 @@ use crate::ResolveError;
|
|||
#[derive(Debug)]
|
||||
pub struct ResolutionGraph {
|
||||
/// The underlying graph.
|
||||
petgraph: petgraph::graph::Graph<Dist, Range<PubGrubVersion>, petgraph::Directed>,
|
||||
petgraph: petgraph::graph::Graph<Dist, Range<Version>, petgraph::Directed>,
|
||||
/// The metadata for every distribution in this resolution.
|
||||
hashes: FxHashMap<PackageName, Vec<Hashes>>,
|
||||
/// The set of editable requirements in this resolution.
|
||||
|
@ -40,12 +40,12 @@ pub struct ResolutionGraph {
|
|||
impl ResolutionGraph {
|
||||
/// Create a new graph from the resolved `PubGrub` state.
|
||||
pub(crate) fn from_state(
|
||||
selection: &SelectedDependencies<PubGrubPackage, PubGrubVersion>,
|
||||
selection: &SelectedDependencies<PubGrubPackage, Version>,
|
||||
pins: &FilePins,
|
||||
packages: &OnceMap<PackageName, VersionMap>,
|
||||
distributions: &OnceMap<PackageId, Metadata21>,
|
||||
redirects: &DashMap<Url, Url>,
|
||||
state: &State<PubGrubPackage, Range<PubGrubVersion>, PubGrubPriority>,
|
||||
state: &State<PubGrubPackage, Range<Version>, PubGrubPriority>,
|
||||
editables: FxHashMap<PackageName, (LocalEditable, Metadata21)>,
|
||||
) -> Result<Self, ResolveError> {
|
||||
// TODO(charlie): petgraph is a really heavy and unnecessary dependency here. We should
|
||||
|
@ -63,7 +63,7 @@ impl ResolutionGraph {
|
|||
PubGrubPackage::Package(package_name, None, None) => {
|
||||
// Create the distribution.
|
||||
let pinned_package = pins
|
||||
.get(package_name, &Version::from(version.clone()))
|
||||
.get(package_name, version)
|
||||
.expect("Every package should be pinned")
|
||||
.clone();
|
||||
|
||||
|
@ -116,9 +116,8 @@ impl ResolutionGraph {
|
|||
let metadata = entry.value();
|
||||
|
||||
if !metadata.provides_extras.contains(extra) {
|
||||
let version = Version::from(version.clone());
|
||||
let pinned_package = pins
|
||||
.get(package_name, &version)
|
||||
.get(package_name, version)
|
||||
.expect("Every package should be pinned")
|
||||
.clone();
|
||||
|
||||
|
@ -208,9 +207,7 @@ impl ResolutionGraph {
|
|||
}
|
||||
|
||||
/// Return the underlying graph.
|
||||
pub fn petgraph(
|
||||
&self,
|
||||
) -> &petgraph::graph::Graph<Dist, Range<PubGrubVersion>, petgraph::Directed> {
|
||||
pub fn petgraph(&self) -> &petgraph::graph::Graph<Dist, Range<Version>, petgraph::Directed> {
|
||||
&self.petgraph
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,7 +21,7 @@ use distribution_types::{
|
|||
BuiltDist, Dist, DistributionMetadata, LocalEditable, Name, PackageId, RemoteSource,
|
||||
SourceDist, VersionOrUrl,
|
||||
};
|
||||
use pep440_rs::VersionSpecifiers;
|
||||
use pep440_rs::{Version, VersionSpecifiers, MIN_VERSION};
|
||||
use pep508_rs::{MarkerEnvironment, Requirement};
|
||||
use platform_tags::Tags;
|
||||
use puffin_client::RegistryClient;
|
||||
|
@ -38,7 +38,7 @@ use crate::overrides::Overrides;
|
|||
use crate::pins::FilePins;
|
||||
use crate::pubgrub::{
|
||||
PubGrubDependencies, PubGrubDistribution, PubGrubPackage, PubGrubPriorities, PubGrubPython,
|
||||
PubGrubSpecifier, PubGrubVersion, MIN_VERSION,
|
||||
PubGrubSpecifier,
|
||||
};
|
||||
use crate::python_requirement::PythonRequirement;
|
||||
use crate::resolution::ResolutionGraph;
|
||||
|
@ -244,7 +244,7 @@ impl<'a, Provider: ResolverProvider> Resolver<'a, Provider> {
|
|||
|
||||
// Start the solve.
|
||||
let mut state = State::init(root.clone(), MIN_VERSION.clone());
|
||||
let mut added_dependencies: FxHashMap<PubGrubPackage, FxHashSet<PubGrubVersion>> =
|
||||
let mut added_dependencies: FxHashMap<PubGrubPackage, FxHashSet<Version>> =
|
||||
FxHashMap::default();
|
||||
let mut next = root;
|
||||
|
||||
|
@ -393,7 +393,7 @@ impl<'a, Provider: ResolverProvider> Resolver<'a, Provider> {
|
|||
/// Visit the set of [`PubGrubPackage`] candidates prior to selection. This allows us to fetch
|
||||
/// metadata for all of the packages in parallel.
|
||||
fn pre_visit<'data>(
|
||||
packages: impl Iterator<Item = (&'data PubGrubPackage, &'data Range<PubGrubVersion>)>,
|
||||
packages: impl Iterator<Item = (&'data PubGrubPackage, &'data Range<Version>)>,
|
||||
request_sink: &futures::channel::mpsc::UnboundedSender<Request>,
|
||||
) -> Result<(), ResolveError> {
|
||||
// Iterate over the potential packages, and fetch file metadata for any of them. These
|
||||
|
@ -412,26 +412,26 @@ impl<'a, Provider: ResolverProvider> Resolver<'a, Provider> {
|
|||
async fn choose_version(
|
||||
&self,
|
||||
package: &PubGrubPackage,
|
||||
range: &Range<PubGrubVersion>,
|
||||
range: &Range<Version>,
|
||||
pins: &mut FilePins,
|
||||
request_sink: &futures::channel::mpsc::UnboundedSender<Request>,
|
||||
) -> Result<Option<PubGrubVersion>, ResolveError> {
|
||||
) -> Result<Option<Version>, ResolveError> {
|
||||
return match package {
|
||||
PubGrubPackage::Root(_) => Ok(Some(MIN_VERSION.clone())),
|
||||
|
||||
PubGrubPackage::Python(PubGrubPython::Installed) => {
|
||||
let version = PubGrubVersion::from(self.python_requirement.installed().clone());
|
||||
if range.contains(&version) {
|
||||
Ok(Some(version))
|
||||
let version = self.python_requirement.installed();
|
||||
if range.contains(version) {
|
||||
Ok(Some(version.clone()))
|
||||
} else {
|
||||
Ok(None)
|
||||
}
|
||||
}
|
||||
|
||||
PubGrubPackage::Python(PubGrubPython::Target) => {
|
||||
let version = PubGrubVersion::from(self.python_requirement.target().clone());
|
||||
if range.contains(&version) {
|
||||
Ok(Some(version))
|
||||
let version = self.python_requirement.target();
|
||||
if range.contains(version) {
|
||||
Ok(Some(version.clone()))
|
||||
} else {
|
||||
Ok(None)
|
||||
}
|
||||
|
@ -458,7 +458,7 @@ impl<'a, Provider: ResolverProvider> Resolver<'a, Provider> {
|
|||
|
||||
if let Ok(wheel_filename) = WheelFilename::try_from(url.raw()) {
|
||||
// If the URL is that of a wheel, extract the version.
|
||||
let version = PubGrubVersion::from(wheel_filename.version);
|
||||
let version = wheel_filename.version;
|
||||
if range.contains(&version) {
|
||||
Ok(Some(version))
|
||||
} else {
|
||||
|
@ -469,9 +469,9 @@ impl<'a, Provider: ResolverProvider> Resolver<'a, Provider> {
|
|||
let dist = PubGrubDistribution::from_url(package_name, url);
|
||||
let entry = self.index.distributions.wait(&dist.package_id()).await;
|
||||
let metadata = entry.value();
|
||||
let version = PubGrubVersion::from(metadata.version.clone());
|
||||
if range.contains(&version) {
|
||||
Ok(Some(version))
|
||||
let version = &metadata.version;
|
||||
if range.contains(version) {
|
||||
Ok(Some(version.clone()))
|
||||
} else {
|
||||
Ok(None)
|
||||
}
|
||||
|
@ -554,7 +554,7 @@ impl<'a, Provider: ResolverProvider> Resolver<'a, Provider> {
|
|||
async fn get_dependencies(
|
||||
&self,
|
||||
package: &PubGrubPackage,
|
||||
version: &PubGrubVersion,
|
||||
version: &Version,
|
||||
priorities: &mut PubGrubPriorities,
|
||||
request_sink: &futures::channel::mpsc::UnboundedSender<Request>,
|
||||
) -> Result<Dependencies, ResolveError> {
|
||||
|
@ -592,7 +592,7 @@ impl<'a, Provider: ResolverProvider> Resolver<'a, Provider> {
|
|||
None,
|
||||
Some(editable.url().clone()),
|
||||
),
|
||||
Range::singleton(PubGrubVersion::from(metadata.version.clone())),
|
||||
Range::singleton(metadata.version.clone()),
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -825,7 +825,7 @@ impl<'a, Provider: ResolverProvider> Resolver<'a, Provider> {
|
|||
}
|
||||
}
|
||||
|
||||
fn on_progress(&self, package: &PubGrubPackage, version: &PubGrubVersion) {
|
||||
fn on_progress(&self, package: &PubGrubPackage, version: &Version) {
|
||||
if let Some(reporter) = self.reporter.as_ref() {
|
||||
match package {
|
||||
PubGrubPackage::Root(_) => {}
|
||||
|
@ -834,7 +834,7 @@ impl<'a, Provider: ResolverProvider> Resolver<'a, Provider> {
|
|||
reporter.on_progress(package_name, VersionOrUrl::Url(url));
|
||||
}
|
||||
PubGrubPackage::Package(package_name, _extra, None) => {
|
||||
reporter.on_progress(package_name, VersionOrUrl::Version(version.into()));
|
||||
reporter.on_progress(package_name, VersionOrUrl::Version(version));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -856,7 +856,7 @@ enum Request {
|
|||
/// A request to fetch the metadata for a built or source distribution.
|
||||
Dist(Dist),
|
||||
/// A request to pre-fetch the metadata for a package and the best-guess distribution.
|
||||
Prefetch(PackageName, Range<PubGrubVersion>),
|
||||
Prefetch(PackageName, Range<Version>),
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
|
@ -879,5 +879,5 @@ enum Dependencies {
|
|||
/// Package dependencies are not usable
|
||||
Unusable(Option<String>),
|
||||
/// Container for all available package versions.
|
||||
Known(DependencyConstraints<PubGrubPackage, Range<PubGrubVersion>>),
|
||||
Known(DependencyConstraints<PubGrubPackage, Range<Version>>),
|
||||
}
|
||||
|
|
|
@ -14,7 +14,6 @@ use puffin_normalize::PackageName;
|
|||
use puffin_traits::BuildContext;
|
||||
use pypi_types::Metadata21;
|
||||
|
||||
use crate::pubgrub::PubGrubVersion;
|
||||
use crate::python_requirement::PythonRequirement;
|
||||
use crate::version_map::VersionMap;
|
||||
use crate::yanks::AllowedYanks;
|
||||
|
@ -49,7 +48,7 @@ pub trait ResolverProvider: Send + Sync {
|
|||
pub struct DefaultResolverProvider<'a, Context: BuildContext + Send + Sync> {
|
||||
client: &'a RegistryClient,
|
||||
/// These are the entries from `--find-links` that act as overrides for index responses.
|
||||
flat_index: FxHashMap<PackageName, FlatIndex<PubGrubVersion>>,
|
||||
flat_index: FxHashMap<PackageName, FlatIndex>,
|
||||
fetcher: DistributionDatabase<'a, Context>,
|
||||
tags: &'a Tags,
|
||||
python_requirement: PythonRequirement<'a>,
|
||||
|
|
|
@ -6,19 +6,19 @@ use tracing::{instrument, warn};
|
|||
|
||||
use distribution_filename::DistFilename;
|
||||
use distribution_types::{Dist, IndexUrl, PrioritizedDistribution, ResolvableDist};
|
||||
use pep440_rs::Version;
|
||||
use platform_tags::Tags;
|
||||
use puffin_client::{FlatIndex, SimpleMetadata};
|
||||
use puffin_normalize::PackageName;
|
||||
use puffin_warnings::warn_user_once;
|
||||
use pypi_types::{Hashes, Yanked};
|
||||
|
||||
use crate::pubgrub::PubGrubVersion;
|
||||
use crate::python_requirement::PythonRequirement;
|
||||
use crate::yanks::AllowedYanks;
|
||||
|
||||
/// A map from versions to distributions.
|
||||
#[derive(Debug, Default, Clone)]
|
||||
pub struct VersionMap(BTreeMap<PubGrubVersion, PrioritizedDistribution>);
|
||||
pub struct VersionMap(BTreeMap<Version, PrioritizedDistribution>);
|
||||
|
||||
impl VersionMap {
|
||||
/// Initialize a [`VersionMap`] from the given metadata.
|
||||
|
@ -32,10 +32,10 @@ impl VersionMap {
|
|||
python_requirement: &PythonRequirement,
|
||||
allowed_yanks: &AllowedYanks,
|
||||
exclude_newer: Option<&DateTime<Utc>>,
|
||||
flat_index: Option<FlatIndex<PubGrubVersion>>,
|
||||
flat_index: Option<FlatIndex>,
|
||||
) -> Self {
|
||||
// If we have packages of the same name from find links, gives them priority, otherwise start empty
|
||||
let mut version_map: BTreeMap<PubGrubVersion, PrioritizedDistribution> =
|
||||
let mut version_map: BTreeMap<Version, PrioritizedDistribution> =
|
||||
flat_index.map(|overrides| overrides.0).unwrap_or_default();
|
||||
|
||||
// Collect compatible distributions.
|
||||
|
@ -87,7 +87,7 @@ impl VersionMap {
|
|||
file,
|
||||
index.clone(),
|
||||
);
|
||||
match version_map.entry(version.clone().into()) {
|
||||
match version_map.entry(version.clone()) {
|
||||
Entry::Occupied(mut entry) => {
|
||||
entry.get_mut().insert_built(
|
||||
dist,
|
||||
|
@ -112,7 +112,7 @@ impl VersionMap {
|
|||
file,
|
||||
index.clone(),
|
||||
);
|
||||
match version_map.entry(version.clone().into()) {
|
||||
match version_map.entry(version.clone()) {
|
||||
Entry::Occupied(mut entry) => {
|
||||
entry
|
||||
.get_mut()
|
||||
|
@ -135,21 +135,19 @@ impl VersionMap {
|
|||
}
|
||||
|
||||
/// Return the [`DistFile`] for the given version, if any.
|
||||
pub(crate) fn get(&self, version: &PubGrubVersion) -> Option<ResolvableDist> {
|
||||
pub(crate) fn get(&self, version: &Version) -> Option<ResolvableDist> {
|
||||
self.0.get(version).and_then(PrioritizedDistribution::get)
|
||||
}
|
||||
|
||||
/// Return an iterator over the versions and distributions.
|
||||
pub(crate) fn iter(
|
||||
&self,
|
||||
) -> impl DoubleEndedIterator<Item = (&PubGrubVersion, ResolvableDist)> {
|
||||
pub(crate) fn iter(&self) -> impl DoubleEndedIterator<Item = (&Version, ResolvableDist)> {
|
||||
self.0
|
||||
.iter()
|
||||
.filter_map(|(version, dist)| Some((version, dist.get()?)))
|
||||
}
|
||||
|
||||
/// Return the [`Hashes`] for the given version, if any.
|
||||
pub(crate) fn hashes(&self, version: &PubGrubVersion) -> Vec<Hashes> {
|
||||
pub(crate) fn hashes(&self, version: &Version) -> Vec<Hashes> {
|
||||
self.0
|
||||
.get(version)
|
||||
.map(|file| file.hashes().to_vec())
|
||||
|
@ -157,8 +155,8 @@ impl VersionMap {
|
|||
}
|
||||
}
|
||||
|
||||
impl From<FlatIndex<PubGrubVersion>> for VersionMap {
|
||||
fn from(flat_index: FlatIndex<PubGrubVersion>) -> Self {
|
||||
impl From<FlatIndex> for VersionMap {
|
||||
fn from(flat_index: FlatIndex) -> Self {
|
||||
Self(flat_index.0)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue