mirror of
https://github.com/astral-sh/uv.git
synced 2025-11-02 21:02:37 +00:00
Merge uv-pubgrub into uv-pep440 (#8669)
This commit is contained in:
parent
f903cd2cce
commit
e5b8cdba70
18 changed files with 96 additions and 106 deletions
14
Cargo.lock
generated
14
Cargo.lock
generated
|
|
@ -4303,7 +4303,6 @@ dependencies = [
|
||||||
"uv-normalize",
|
"uv-normalize",
|
||||||
"uv-pep440",
|
"uv-pep440",
|
||||||
"uv-pep508",
|
"uv-pep508",
|
||||||
"uv-pubgrub",
|
|
||||||
"uv-pypi-types",
|
"uv-pypi-types",
|
||||||
"uv-warnings",
|
"uv-warnings",
|
||||||
"walkdir",
|
"walkdir",
|
||||||
|
|
@ -4875,6 +4874,7 @@ dependencies = [
|
||||||
"tracing",
|
"tracing",
|
||||||
"unicode-width",
|
"unicode-width",
|
||||||
"unscanny",
|
"unscanny",
|
||||||
|
"version-ranges",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -4900,7 +4900,6 @@ dependencies = [
|
||||||
"uv-fs",
|
"uv-fs",
|
||||||
"uv-normalize",
|
"uv-normalize",
|
||||||
"uv-pep440",
|
"uv-pep440",
|
||||||
"uv-pubgrub",
|
|
||||||
"version-ranges",
|
"version-ranges",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
@ -4929,16 +4928,6 @@ dependencies = [
|
||||||
"thiserror",
|
"thiserror",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "uv-pubgrub"
|
|
||||||
version = "0.0.1"
|
|
||||||
dependencies = [
|
|
||||||
"itertools 0.13.0",
|
|
||||||
"thiserror",
|
|
||||||
"uv-pep440",
|
|
||||||
"version-ranges",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "uv-publish"
|
name = "uv-publish"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
|
|
@ -5158,7 +5147,6 @@ dependencies = [
|
||||||
"uv-pep440",
|
"uv-pep440",
|
||||||
"uv-pep508",
|
"uv-pep508",
|
||||||
"uv-platform-tags",
|
"uv-platform-tags",
|
||||||
"uv-pubgrub",
|
|
||||||
"uv-pypi-types",
|
"uv-pypi-types",
|
||||||
"uv-python",
|
"uv-python",
|
||||||
"uv-requirements-txt",
|
"uv-requirements-txt",
|
||||||
|
|
|
||||||
|
|
@ -46,10 +46,9 @@ uv-metadata = { path = "crates/uv-metadata" }
|
||||||
uv-normalize = { path = "crates/uv-normalize" }
|
uv-normalize = { path = "crates/uv-normalize" }
|
||||||
uv-once-map = { path = "crates/uv-once-map" }
|
uv-once-map = { path = "crates/uv-once-map" }
|
||||||
uv-options-metadata = { path = "crates/uv-options-metadata" }
|
uv-options-metadata = { path = "crates/uv-options-metadata" }
|
||||||
uv-pep440 = { path = "crates/uv-pep440", features = ["tracing", "rkyv"] }
|
uv-pep440 = { path = "crates/uv-pep440", features = ["tracing", "rkyv", "version-ranges"] }
|
||||||
uv-pep508 = { path = "crates/uv-pep508", features = ["non-pep508-extensions"] }
|
uv-pep508 = { path = "crates/uv-pep508", features = ["non-pep508-extensions"] }
|
||||||
uv-platform-tags = { path = "crates/uv-platform-tags" }
|
uv-platform-tags = { path = "crates/uv-platform-tags" }
|
||||||
uv-pubgrub = { path = "crates/uv-pubgrub" }
|
|
||||||
uv-publish = { path = "crates/uv-publish" }
|
uv-publish = { path = "crates/uv-publish" }
|
||||||
uv-pypi-types = { path = "crates/uv-pypi-types" }
|
uv-pypi-types = { path = "crates/uv-pypi-types" }
|
||||||
uv-python = { path = "crates/uv-python" }
|
uv-python = { path = "crates/uv-python" }
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,6 @@ uv-fs = { workspace = true }
|
||||||
uv-normalize = { workspace = true }
|
uv-normalize = { workspace = true }
|
||||||
uv-pep440 = { workspace = true }
|
uv-pep440 = { workspace = true }
|
||||||
uv-pep508 = { workspace = true }
|
uv-pep508 = { workspace = true }
|
||||||
uv-pubgrub = { workspace = true }
|
|
||||||
uv-pypi-types = { workspace = true }
|
uv-pypi-types = { workspace = true }
|
||||||
uv-warnings = { workspace = true }
|
uv-warnings = { workspace = true }
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -9,9 +9,8 @@ use std::str::FromStr;
|
||||||
use tracing::debug;
|
use tracing::debug;
|
||||||
use uv_fs::Simplified;
|
use uv_fs::Simplified;
|
||||||
use uv_normalize::{ExtraName, PackageName};
|
use uv_normalize::{ExtraName, PackageName};
|
||||||
use uv_pep440::{Version, VersionSpecifiers};
|
use uv_pep440::{Version, VersionRangesSpecifier, VersionSpecifiers};
|
||||||
use uv_pep508::{Requirement, VersionOrUrl};
|
use uv_pep508::{Requirement, VersionOrUrl};
|
||||||
use uv_pubgrub::PubGrubSpecifier;
|
|
||||||
use uv_pypi_types::{Metadata23, VerbatimParsedUrl};
|
use uv_pypi_types::{Metadata23, VerbatimParsedUrl};
|
||||||
use uv_warnings::warn_user_once;
|
use uv_warnings::warn_user_once;
|
||||||
|
|
||||||
|
|
@ -135,7 +134,7 @@ impl PyProjectToml {
|
||||||
);
|
);
|
||||||
passed = false;
|
passed = false;
|
||||||
}
|
}
|
||||||
PubGrubSpecifier::from_pep440_specifiers(specifier)
|
VersionRangesSpecifier::from_pep440_specifiers(specifier)
|
||||||
.ok()
|
.ok()
|
||||||
.and_then(|specifier| Some(specifier.bounding_range()?.1 != Bound::Unbounded))
|
.and_then(|specifier| Some(specifier.bounding_range()?.1 != Bound::Unbounded))
|
||||||
.unwrap_or(false)
|
.unwrap_or(false)
|
||||||
|
|
|
||||||
|
|
@ -20,11 +20,12 @@ doctest = false
|
||||||
workspace = true
|
workspace = true
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
serde = { workspace = true, features = ["derive"] }
|
|
||||||
rkyv = { workspace = true, optional = true }
|
rkyv = { workspace = true, optional = true }
|
||||||
|
serde = { workspace = true, features = ["derive"] }
|
||||||
tracing = { workspace = true, optional = true }
|
tracing = { workspace = true, optional = true }
|
||||||
unicode-width = { workspace = true }
|
unicode-width = { workspace = true }
|
||||||
unscanny = { workspace = true }
|
unscanny = { workspace = true }
|
||||||
|
version-ranges = { workspace = true, optional = true }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
indoc = { version = "2.0.5" }
|
indoc = { version = "2.0.5" }
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,8 @@
|
||||||
//! the version matching needs to catch all sorts of special cases
|
//! the version matching needs to catch all sorts of special cases
|
||||||
#![warn(missing_docs)]
|
#![warn(missing_docs)]
|
||||||
|
|
||||||
|
#[cfg(feature = "version-ranges")]
|
||||||
|
pub use version_ranges_specifier::{VersionRangesSpecifier, VersionRangesSpecifierError};
|
||||||
pub use {
|
pub use {
|
||||||
version::{
|
version::{
|
||||||
LocalSegment, Operator, OperatorParseError, Prerelease, PrereleaseKind, Version,
|
LocalSegment, Operator, OperatorParseError, Prerelease, PrereleaseKind, Version,
|
||||||
|
|
@ -39,3 +41,5 @@ mod version_specifier;
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests;
|
mod tests;
|
||||||
|
#[cfg(feature = "version-ranges")]
|
||||||
|
mod version_ranges_specifier;
|
||||||
|
|
|
||||||
|
|
@ -1,58 +1,73 @@
|
||||||
|
use std::error::Error;
|
||||||
|
use std::fmt::{Display, Formatter};
|
||||||
use std::ops::Bound;
|
use std::ops::Bound;
|
||||||
|
|
||||||
use itertools::Itertools;
|
|
||||||
use thiserror::Error;
|
|
||||||
use version_ranges::Ranges;
|
use version_ranges::Ranges;
|
||||||
|
|
||||||
use uv_pep440::{Operator, Prerelease, Version, VersionSpecifier, VersionSpecifiers};
|
use crate::{Operator, Prerelease, Version, VersionSpecifier, VersionSpecifiers};
|
||||||
|
|
||||||
#[derive(Debug, Error)]
|
/// The conversion between PEP 440 [`VersionSpecifier`] and version-ranges
|
||||||
pub enum PubGrubSpecifierError {
|
/// [`VersionRangesSpecifier`] failed.
|
||||||
#[error("~= operator requires at least two release segments: `{0}`")]
|
#[derive(Debug)]
|
||||||
|
pub enum VersionRangesSpecifierError {
|
||||||
|
/// The `~=` operator requires at least two release segments
|
||||||
InvalidTildeEquals(VersionSpecifier),
|
InvalidTildeEquals(VersionSpecifier),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Error for VersionRangesSpecifierError {}
|
||||||
|
|
||||||
|
impl Display for VersionRangesSpecifierError {
|
||||||
|
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||||
|
match self {
|
||||||
|
Self::InvalidTildeEquals(specifier) => {
|
||||||
|
write!(
|
||||||
|
f,
|
||||||
|
"The `~=` operator requires at least two release segments: `{specifier}`"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// A range of versions that can be used to satisfy a requirement.
|
/// A range of versions that can be used to satisfy a requirement.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct PubGrubSpecifier(Ranges<Version>);
|
pub struct VersionRangesSpecifier(Ranges<Version>);
|
||||||
|
|
||||||
impl PubGrubSpecifier {
|
impl VersionRangesSpecifier {
|
||||||
/// Returns an iterator over the bounds of the [`PubGrubSpecifier`].
|
/// Returns an iterator over the bounds of the [`VersionRangesSpecifier`].
|
||||||
pub fn iter(&self) -> impl Iterator<Item = (&Bound<Version>, &Bound<Version>)> {
|
pub fn iter(&self) -> impl Iterator<Item = (&Bound<Version>, &Bound<Version>)> {
|
||||||
self.0.iter()
|
self.0.iter()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return the bounding [`Ranges`] of the [`PubGrubSpecifier`].
|
/// Return the bounding [`Ranges`] of the [`VersionRangesSpecifier`].
|
||||||
pub fn bounding_range(&self) -> Option<(Bound<&Version>, Bound<&Version>)> {
|
pub fn bounding_range(&self) -> Option<(Bound<&Version>, Bound<&Version>)> {
|
||||||
self.0.bounding_range()
|
self.0.bounding_range()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<Ranges<Version>> for PubGrubSpecifier {
|
impl From<Ranges<Version>> for VersionRangesSpecifier {
|
||||||
fn from(range: Ranges<Version>) -> Self {
|
fn from(range: Ranges<Version>) -> Self {
|
||||||
PubGrubSpecifier(range)
|
VersionRangesSpecifier(range)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<PubGrubSpecifier> for Ranges<Version> {
|
impl From<VersionRangesSpecifier> for Ranges<Version> {
|
||||||
/// Convert a PubGrub specifier to a range of versions.
|
/// Convert a PubGrub specifier to a range of versions.
|
||||||
fn from(specifier: PubGrubSpecifier) -> Self {
|
fn from(specifier: VersionRangesSpecifier) -> Self {
|
||||||
specifier.0
|
specifier.0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PubGrubSpecifier {
|
impl VersionRangesSpecifier {
|
||||||
/// Convert [`VersionSpecifiers`] to a PubGrub-compatible version range, using PEP 440
|
/// Convert [`VersionSpecifiers`] to a PubGrub-compatible version range, using PEP 440
|
||||||
/// semantics.
|
/// semantics.
|
||||||
pub fn from_pep440_specifiers(
|
pub fn from_pep440_specifiers(
|
||||||
specifiers: &VersionSpecifiers,
|
specifiers: &VersionSpecifiers,
|
||||||
) -> Result<Self, PubGrubSpecifierError> {
|
) -> Result<Self, VersionRangesSpecifierError> {
|
||||||
let range = specifiers
|
let mut range = Ranges::full();
|
||||||
.iter()
|
for specifier in specifiers.iter() {
|
||||||
.map(Self::from_pep440_specifier)
|
range = range.intersection(&Self::from_pep440_specifier(specifier)?.into());
|
||||||
.fold_ok(Ranges::full(), |range, specifier| {
|
}
|
||||||
range.intersection(&specifier.into())
|
|
||||||
})?;
|
|
||||||
Ok(Self(range))
|
Ok(Self(range))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -60,7 +75,7 @@ impl PubGrubSpecifier {
|
||||||
/// semantics.
|
/// semantics.
|
||||||
pub fn from_pep440_specifier(
|
pub fn from_pep440_specifier(
|
||||||
specifier: &VersionSpecifier,
|
specifier: &VersionSpecifier,
|
||||||
) -> Result<Self, PubGrubSpecifierError> {
|
) -> Result<Self, VersionRangesSpecifierError> {
|
||||||
let ranges = match specifier.operator() {
|
let ranges = match specifier.operator() {
|
||||||
Operator::Equal => {
|
Operator::Equal => {
|
||||||
let version = specifier.version().clone();
|
let version = specifier.version().clone();
|
||||||
|
|
@ -76,7 +91,9 @@ impl PubGrubSpecifier {
|
||||||
}
|
}
|
||||||
Operator::TildeEqual => {
|
Operator::TildeEqual => {
|
||||||
let [rest @ .., last, _] = specifier.version().release() else {
|
let [rest @ .., last, _] = specifier.version().release() else {
|
||||||
return Err(PubGrubSpecifierError::InvalidTildeEquals(specifier.clone()));
|
return Err(VersionRangesSpecifierError::InvalidTildeEquals(
|
||||||
|
specifier.clone(),
|
||||||
|
));
|
||||||
};
|
};
|
||||||
let upper = Version::new(rest.iter().chain([&(last + 1)]))
|
let upper = Version::new(rest.iter().chain([&(last + 1)]))
|
||||||
.with_epoch(specifier.version().epoch())
|
.with_epoch(specifier.version().epoch())
|
||||||
|
|
@ -167,13 +184,11 @@ impl PubGrubSpecifier {
|
||||||
/// See: <https://github.com/pypa/pip/blob/a432c7f4170b9ef798a15f035f5dfdb4cc939f35/src/pip/_internal/resolution/resolvelib/candidates.py#L540>
|
/// See: <https://github.com/pypa/pip/blob/a432c7f4170b9ef798a15f035f5dfdb4cc939f35/src/pip/_internal/resolution/resolvelib/candidates.py#L540>
|
||||||
pub fn from_release_specifiers(
|
pub fn from_release_specifiers(
|
||||||
specifiers: &VersionSpecifiers,
|
specifiers: &VersionSpecifiers,
|
||||||
) -> Result<Self, PubGrubSpecifierError> {
|
) -> Result<Self, VersionRangesSpecifierError> {
|
||||||
let range = specifiers
|
let mut range = Ranges::full();
|
||||||
.iter()
|
for specifier in specifiers.iter() {
|
||||||
.map(Self::from_release_specifier)
|
range = range.intersection(&Self::from_release_specifier(specifier)?.into());
|
||||||
.fold_ok(Ranges::full(), |range, specifier| {
|
}
|
||||||
range.intersection(&specifier.into())
|
|
||||||
})?;
|
|
||||||
Ok(Self(range))
|
Ok(Self(range))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -190,7 +205,7 @@ impl PubGrubSpecifier {
|
||||||
/// See: <https://github.com/pypa/pip/blob/a432c7f4170b9ef798a15f035f5dfdb4cc939f35/src/pip/_internal/resolution/resolvelib/candidates.py#L540>
|
/// See: <https://github.com/pypa/pip/blob/a432c7f4170b9ef798a15f035f5dfdb4cc939f35/src/pip/_internal/resolution/resolvelib/candidates.py#L540>
|
||||||
pub fn from_release_specifier(
|
pub fn from_release_specifier(
|
||||||
specifier: &VersionSpecifier,
|
specifier: &VersionSpecifier,
|
||||||
) -> Result<Self, PubGrubSpecifierError> {
|
) -> Result<Self, VersionRangesSpecifierError> {
|
||||||
let ranges = match specifier.operator() {
|
let ranges = match specifier.operator() {
|
||||||
Operator::Equal => {
|
Operator::Equal => {
|
||||||
let version = specifier.version().only_release();
|
let version = specifier.version().only_release();
|
||||||
|
|
@ -206,7 +221,9 @@ impl PubGrubSpecifier {
|
||||||
}
|
}
|
||||||
Operator::TildeEqual => {
|
Operator::TildeEqual => {
|
||||||
let [rest @ .., last, _] = specifier.version().release() else {
|
let [rest @ .., last, _] = specifier.version().release() else {
|
||||||
return Err(PubGrubSpecifierError::InvalidTildeEquals(specifier.clone()));
|
return Err(VersionRangesSpecifierError::InvalidTildeEquals(
|
||||||
|
specifier.clone(),
|
||||||
|
));
|
||||||
};
|
};
|
||||||
let upper = Version::new(rest.iter().chain([&(last + 1)]));
|
let upper = Version::new(rest.iter().chain([&(last + 1)]));
|
||||||
let version = specifier.version().only_release();
|
let version = specifier.version().only_release();
|
||||||
|
|
@ -24,7 +24,6 @@ workspace = true
|
||||||
uv-fs = { workspace = true }
|
uv-fs = { workspace = true }
|
||||||
uv-normalize = { workspace = true }
|
uv-normalize = { workspace = true }
|
||||||
uv-pep440 = { workspace = true }
|
uv-pep440 = { workspace = true }
|
||||||
uv-pubgrub = { workspace = true }
|
|
||||||
|
|
||||||
boxcar = { workspace = true }
|
boxcar = { workspace = true }
|
||||||
indexmap = { workspace = true }
|
indexmap = { workspace = true }
|
||||||
|
|
|
||||||
|
|
@ -53,9 +53,8 @@ use std::sync::MutexGuard;
|
||||||
use itertools::Either;
|
use itertools::Either;
|
||||||
use rustc_hash::FxHashMap;
|
use rustc_hash::FxHashMap;
|
||||||
use std::sync::LazyLock;
|
use std::sync::LazyLock;
|
||||||
use uv_pep440::Operator;
|
use uv_pep440::{Operator, VersionRangesSpecifier};
|
||||||
use uv_pep440::{Version, VersionSpecifier};
|
use uv_pep440::{Version, VersionSpecifier};
|
||||||
use uv_pubgrub::PubGrubSpecifier;
|
|
||||||
use version_ranges::Ranges;
|
use version_ranges::Ranges;
|
||||||
|
|
||||||
use crate::marker::MarkerValueExtra;
|
use crate::marker::MarkerValueExtra;
|
||||||
|
|
@ -746,7 +745,8 @@ impl Edges {
|
||||||
/// Returns the [`Edges`] for a version specifier.
|
/// Returns the [`Edges`] for a version specifier.
|
||||||
fn from_specifier(specifier: VersionSpecifier) -> Edges {
|
fn from_specifier(specifier: VersionSpecifier) -> Edges {
|
||||||
let specifier =
|
let specifier =
|
||||||
PubGrubSpecifier::from_release_specifier(&normalize_specifier(specifier)).unwrap();
|
VersionRangesSpecifier::from_release_specifier(&normalize_specifier(specifier))
|
||||||
|
.unwrap();
|
||||||
Edges::Version {
|
Edges::Version {
|
||||||
edges: Edges::from_range(&specifier.into()),
|
edges: Edges::from_range(&specifier.into()),
|
||||||
}
|
}
|
||||||
|
|
@ -764,7 +764,8 @@ impl Edges {
|
||||||
let specifier = VersionSpecifier::equals_version(version.clone());
|
let specifier = VersionSpecifier::equals_version(version.clone());
|
||||||
let specifier = python_version_to_full_version(specifier)?;
|
let specifier = python_version_to_full_version(specifier)?;
|
||||||
let pubgrub_specifier =
|
let pubgrub_specifier =
|
||||||
PubGrubSpecifier::from_release_specifier(&normalize_specifier(specifier)).unwrap();
|
VersionRangesSpecifier::from_release_specifier(&normalize_specifier(specifier))
|
||||||
|
.unwrap();
|
||||||
range = range.union(&pubgrub_specifier.into());
|
range = range.union(&pubgrub_specifier.into());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,18 +0,0 @@
|
||||||
[package]
|
|
||||||
name = "uv-pubgrub"
|
|
||||||
version = "0.0.1"
|
|
||||||
edition = "2021"
|
|
||||||
description = "Common uv pubgrub types."
|
|
||||||
|
|
||||||
[lib]
|
|
||||||
doctest = false
|
|
||||||
|
|
||||||
[lints]
|
|
||||||
workspace = true
|
|
||||||
|
|
||||||
[dependencies]
|
|
||||||
uv-pep440 = { workspace = true }
|
|
||||||
|
|
||||||
itertools = { workspace = true }
|
|
||||||
thiserror = { workspace = true }
|
|
||||||
version-ranges = { workspace = true }
|
|
||||||
|
|
@ -30,7 +30,6 @@ uv-once-map = { workspace = true }
|
||||||
uv-pep440 = { workspace = true }
|
uv-pep440 = { workspace = true }
|
||||||
uv-pep508 = { workspace = true }
|
uv-pep508 = { workspace = true }
|
||||||
uv-platform-tags = { workspace = true }
|
uv-platform-tags = { workspace = true }
|
||||||
uv-pubgrub = { workspace = true }
|
|
||||||
uv-pypi-types = { workspace = true }
|
uv-pypi-types = { workspace = true }
|
||||||
uv-python = { workspace = true }
|
uv-python = { workspace = true }
|
||||||
uv-requirements-txt = { workspace = true }
|
uv-requirements-txt = { workspace = true }
|
||||||
|
|
|
||||||
|
|
@ -9,9 +9,7 @@ use rustc_hash::FxHashMap;
|
||||||
use crate::candidate_selector::CandidateSelector;
|
use crate::candidate_selector::CandidateSelector;
|
||||||
use crate::dependency_provider::UvDependencyProvider;
|
use crate::dependency_provider::UvDependencyProvider;
|
||||||
use crate::fork_urls::ForkUrls;
|
use crate::fork_urls::ForkUrls;
|
||||||
use crate::pubgrub::{
|
use crate::pubgrub::{PubGrubPackage, PubGrubPackageInner, PubGrubReportFormatter};
|
||||||
PubGrubPackage, PubGrubPackageInner, PubGrubReportFormatter, PubGrubSpecifierError,
|
|
||||||
};
|
|
||||||
use crate::python_requirement::PythonRequirement;
|
use crate::python_requirement::PythonRequirement;
|
||||||
use crate::resolution::ConflictingDistributionError;
|
use crate::resolution::ConflictingDistributionError;
|
||||||
use crate::resolver::{IncompletePackage, ResolverMarkers, UnavailablePackage, UnavailableReason};
|
use crate::resolver::{IncompletePackage, ResolverMarkers, UnavailablePackage, UnavailableReason};
|
||||||
|
|
@ -21,7 +19,7 @@ use uv_distribution_types::{
|
||||||
BuiltDist, IndexCapabilities, IndexLocations, IndexUrl, InstalledDist, SourceDist,
|
BuiltDist, IndexCapabilities, IndexLocations, IndexUrl, InstalledDist, SourceDist,
|
||||||
};
|
};
|
||||||
use uv_normalize::PackageName;
|
use uv_normalize::PackageName;
|
||||||
use uv_pep440::Version;
|
use uv_pep440::{Version, VersionRangesSpecifierError};
|
||||||
use uv_pep508::MarkerTree;
|
use uv_pep508::MarkerTree;
|
||||||
use uv_static::EnvVars;
|
use uv_static::EnvVars;
|
||||||
|
|
||||||
|
|
@ -40,7 +38,7 @@ pub enum ResolveError {
|
||||||
UnregisteredTask(String),
|
UnregisteredTask(String),
|
||||||
|
|
||||||
#[error(transparent)]
|
#[error(transparent)]
|
||||||
PubGrubSpecifier(#[from] PubGrubSpecifierError),
|
VersionRangesSpecifier(#[from] VersionRangesSpecifierError),
|
||||||
|
|
||||||
#[error("Overrides contain conflicting URLs for package `{0}`:\n- {1}\n- {2}")]
|
#[error("Overrides contain conflicting URLs for package `{0}`:\n- {1}\n- {2}")]
|
||||||
ConflictingOverrideUrls(PackageName, String, String),
|
ConflictingOverrideUrls(PackageName, String, String),
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,6 @@ pub use manifest::Manifest;
|
||||||
pub use options::{Flexibility, Options, OptionsBuilder};
|
pub use options::{Flexibility, Options, OptionsBuilder};
|
||||||
pub use preferences::{Preference, PreferenceError, Preferences};
|
pub use preferences::{Preference, PreferenceError, Preferences};
|
||||||
pub use prerelease::PrereleaseMode;
|
pub use prerelease::PrereleaseMode;
|
||||||
pub use pubgrub::{PubGrubSpecifier, PubGrubSpecifierError};
|
|
||||||
pub use python_requirement::PythonRequirement;
|
pub use python_requirement::PythonRequirement;
|
||||||
pub use requires_python::{RequiresPython, RequiresPythonError, RequiresPythonRange};
|
pub use requires_python::{RequiresPython, RequiresPythonError, RequiresPythonRange};
|
||||||
pub use resolution::{
|
pub use resolution::{
|
||||||
|
|
|
||||||
|
|
@ -5,14 +5,14 @@ use pubgrub::Range;
|
||||||
use tracing::warn;
|
use tracing::warn;
|
||||||
|
|
||||||
use uv_normalize::{ExtraName, PackageName};
|
use uv_normalize::{ExtraName, PackageName};
|
||||||
use uv_pep440::{Version, VersionSpecifiers};
|
use uv_pep440::{Version, VersionRangesSpecifier, VersionSpecifiers};
|
||||||
use uv_pypi_types::{
|
use uv_pypi_types::{
|
||||||
ParsedArchiveUrl, ParsedDirectoryUrl, ParsedGitUrl, ParsedPathUrl, ParsedUrl, Requirement,
|
ParsedArchiveUrl, ParsedDirectoryUrl, ParsedGitUrl, ParsedPathUrl, ParsedUrl, Requirement,
|
||||||
RequirementSource, VerbatimParsedUrl,
|
RequirementSource, VerbatimParsedUrl,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::pubgrub::{PubGrubPackage, PubGrubPackageInner};
|
use crate::pubgrub::{PubGrubPackage, PubGrubPackageInner};
|
||||||
use crate::{PubGrubSpecifier, ResolveError};
|
use crate::ResolveError;
|
||||||
|
|
||||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||||
pub(crate) struct PubGrubDependency {
|
pub(crate) struct PubGrubDependency {
|
||||||
|
|
@ -179,7 +179,7 @@ impl PubGrubRequirement {
|
||||||
extra: Option<ExtraName>,
|
extra: Option<ExtraName>,
|
||||||
requirement: &Requirement,
|
requirement: &Requirement,
|
||||||
) -> Result<PubGrubRequirement, ResolveError> {
|
) -> Result<PubGrubRequirement, ResolveError> {
|
||||||
let version = PubGrubSpecifier::from_pep440_specifiers(specifier)?.into();
|
let version = VersionRangesSpecifier::from_pep440_specifiers(specifier)?.into();
|
||||||
|
|
||||||
let requirement = Self {
|
let requirement = Self {
|
||||||
package: PubGrubPackage::from_package(
|
package: PubGrubPackage::from_package(
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,6 @@ pub(crate) use crate::pubgrub::distribution::PubGrubDistribution;
|
||||||
pub(crate) use crate::pubgrub::package::{PubGrubPackage, PubGrubPackageInner, PubGrubPython};
|
pub(crate) use crate::pubgrub::package::{PubGrubPackage, PubGrubPackageInner, PubGrubPython};
|
||||||
pub(crate) use crate::pubgrub::priority::{PubGrubPriorities, PubGrubPriority};
|
pub(crate) use crate::pubgrub::priority::{PubGrubPriorities, PubGrubPriority};
|
||||||
pub(crate) use crate::pubgrub::report::PubGrubReportFormatter;
|
pub(crate) use crate::pubgrub::report::PubGrubReportFormatter;
|
||||||
pub use uv_pubgrub::{PubGrubSpecifier, PubGrubSpecifierError};
|
|
||||||
|
|
||||||
mod dependencies;
|
mod dependencies;
|
||||||
mod distribution;
|
mod distribution;
|
||||||
|
|
|
||||||
|
|
@ -5,14 +5,16 @@ use std::collections::Bound;
|
||||||
use std::ops::Deref;
|
use std::ops::Deref;
|
||||||
|
|
||||||
use uv_distribution_filename::WheelFilename;
|
use uv_distribution_filename::WheelFilename;
|
||||||
use uv_pep440::{Version, VersionSpecifier, VersionSpecifiers};
|
use uv_pep440::{
|
||||||
|
Version, VersionRangesSpecifier, VersionRangesSpecifierError, VersionSpecifier,
|
||||||
|
VersionSpecifiers,
|
||||||
|
};
|
||||||
use uv_pep508::{MarkerExpression, MarkerTree, MarkerValueVersion};
|
use uv_pep508::{MarkerExpression, MarkerTree, MarkerValueVersion};
|
||||||
use uv_pubgrub::PubGrubSpecifier;
|
|
||||||
|
|
||||||
#[derive(thiserror::Error, Debug)]
|
#[derive(thiserror::Error, Debug)]
|
||||||
pub enum RequiresPythonError {
|
pub enum RequiresPythonError {
|
||||||
#[error(transparent)]
|
#[error(transparent)]
|
||||||
PubGrub(#[from] crate::pubgrub::PubGrubSpecifierError),
|
VersionRangesSpecifier(#[from] VersionRangesSpecifierError),
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The `Requires-Python` requirement specifier.
|
/// The `Requires-Python` requirement specifier.
|
||||||
|
|
@ -53,10 +55,11 @@ impl RequiresPython {
|
||||||
|
|
||||||
/// Returns a [`RequiresPython`] from a version specifier.
|
/// Returns a [`RequiresPython`] from a version specifier.
|
||||||
pub fn from_specifiers(specifiers: &VersionSpecifiers) -> Result<Self, RequiresPythonError> {
|
pub fn from_specifiers(specifiers: &VersionSpecifiers) -> Result<Self, RequiresPythonError> {
|
||||||
let (lower_bound, upper_bound) = PubGrubSpecifier::from_release_specifiers(specifiers)?
|
let (lower_bound, upper_bound) =
|
||||||
.bounding_range()
|
VersionRangesSpecifier::from_release_specifiers(specifiers)?
|
||||||
.map(|(lower_bound, upper_bound)| (lower_bound.cloned(), upper_bound.cloned()))
|
.bounding_range()
|
||||||
.unwrap_or((Bound::Unbounded, Bound::Unbounded));
|
.map(|(lower_bound, upper_bound)| (lower_bound.cloned(), upper_bound.cloned()))
|
||||||
|
.unwrap_or((Bound::Unbounded, Bound::Unbounded));
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
specifiers: specifiers.clone(),
|
specifiers: specifiers.clone(),
|
||||||
range: RequiresPythonRange(LowerBound(lower_bound), UpperBound(upper_bound)),
|
range: RequiresPythonRange(LowerBound(lower_bound), UpperBound(upper_bound)),
|
||||||
|
|
@ -72,7 +75,7 @@ impl RequiresPython {
|
||||||
// Convert to PubGrub range and perform an intersection.
|
// Convert to PubGrub range and perform an intersection.
|
||||||
let range = specifiers
|
let range = specifiers
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(PubGrubSpecifier::from_release_specifiers)
|
.map(VersionRangesSpecifier::from_release_specifiers)
|
||||||
.fold_ok(None, |range: Option<Range<Version>>, requires_python| {
|
.fold_ok(None, |range: Option<Range<Version>>, requires_python| {
|
||||||
if let Some(range) = range {
|
if let Some(range) = range {
|
||||||
Some(range.intersection(&requires_python.into()))
|
Some(range.intersection(&requires_python.into()))
|
||||||
|
|
@ -237,7 +240,7 @@ impl RequiresPython {
|
||||||
/// provided range. However, `>=3.9` would not be considered compatible, as the
|
/// provided range. However, `>=3.9` would not be considered compatible, as the
|
||||||
/// `Requires-Python` includes Python 3.8, but `>=3.9` does not.
|
/// `Requires-Python` includes Python 3.8, but `>=3.9` does not.
|
||||||
pub fn is_contained_by(&self, target: &VersionSpecifiers) -> bool {
|
pub fn is_contained_by(&self, target: &VersionSpecifiers) -> bool {
|
||||||
let Ok(target) = PubGrubSpecifier::from_release_specifiers(target) else {
|
let Ok(target) = VersionRangesSpecifier::from_release_specifiers(target) else {
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
let target = target
|
let target = target
|
||||||
|
|
@ -485,11 +488,12 @@ impl serde::Serialize for RequiresPython {
|
||||||
impl<'de> serde::Deserialize<'de> for RequiresPython {
|
impl<'de> serde::Deserialize<'de> for RequiresPython {
|
||||||
fn deserialize<D: serde::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
|
fn deserialize<D: serde::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
|
||||||
let specifiers = VersionSpecifiers::deserialize(deserializer)?;
|
let specifiers = VersionSpecifiers::deserialize(deserializer)?;
|
||||||
let (lower_bound, upper_bound) = PubGrubSpecifier::from_release_specifiers(&specifiers)
|
let (lower_bound, upper_bound) =
|
||||||
.map_err(serde::de::Error::custom)?
|
VersionRangesSpecifier::from_release_specifiers(&specifiers)
|
||||||
.bounding_range()
|
.map_err(serde::de::Error::custom)?
|
||||||
.map(|(lower_bound, upper_bound)| (lower_bound.cloned(), upper_bound.cloned()))
|
.bounding_range()
|
||||||
.unwrap_or((Bound::Unbounded, Bound::Unbounded));
|
.map(|(lower_bound, upper_bound)| (lower_bound.cloned(), upper_bound.cloned()))
|
||||||
|
.unwrap_or((Bound::Unbounded, Bound::Unbounded));
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
specifiers,
|
specifiers,
|
||||||
range: RequiresPythonRange(LowerBound(lower_bound), UpperBound(upper_bound)),
|
range: RequiresPythonRange(LowerBound(lower_bound), UpperBound(upper_bound)),
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,7 @@ use uv_distribution_types::{
|
||||||
};
|
};
|
||||||
use uv_git::GitResolver;
|
use uv_git::GitResolver;
|
||||||
use uv_normalize::{ExtraName, GroupName, PackageName};
|
use uv_normalize::{ExtraName, GroupName, PackageName};
|
||||||
use uv_pep440::{Version, MIN_VERSION};
|
use uv_pep440::{Version, VersionRangesSpecifier, MIN_VERSION};
|
||||||
use uv_pep508::MarkerTree;
|
use uv_pep508::MarkerTree;
|
||||||
use uv_platform_tags::Tags;
|
use uv_platform_tags::Tags;
|
||||||
use uv_pypi_types::{Requirement, ResolutionMetadata, VerbatimParsedUrl};
|
use uv_pypi_types::{Requirement, ResolutionMetadata, VerbatimParsedUrl};
|
||||||
|
|
@ -51,7 +51,7 @@ use crate::pins::FilePins;
|
||||||
use crate::preferences::Preferences;
|
use crate::preferences::Preferences;
|
||||||
use crate::pubgrub::{
|
use crate::pubgrub::{
|
||||||
PubGrubDependency, PubGrubDistribution, PubGrubPackage, PubGrubPackageInner, PubGrubPriorities,
|
PubGrubDependency, PubGrubDistribution, PubGrubPackage, PubGrubPackageInner, PubGrubPriorities,
|
||||||
PubGrubPython, PubGrubSpecifier,
|
PubGrubPython,
|
||||||
};
|
};
|
||||||
use crate::python_requirement::PythonRequirement;
|
use crate::python_requirement::PythonRequirement;
|
||||||
use crate::resolution::ResolutionGraph;
|
use crate::resolution::ResolutionGraph;
|
||||||
|
|
@ -2224,7 +2224,9 @@ impl ForkState {
|
||||||
Locals::map(local, specifier)
|
Locals::map(local, specifier)
|
||||||
.map_err(ResolveError::InvalidVersion)
|
.map_err(ResolveError::InvalidVersion)
|
||||||
.and_then(|specifier| {
|
.and_then(|specifier| {
|
||||||
Ok(PubGrubSpecifier::from_pep440_specifier(&specifier)?)
|
Ok(VersionRangesSpecifier::from_pep440_specifier(
|
||||||
|
&specifier,
|
||||||
|
)?)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
.fold_ok(Range::full(), |range, specifier| {
|
.fold_ok(Range::full(), |range, specifier| {
|
||||||
|
|
@ -2300,7 +2302,7 @@ impl ForkState {
|
||||||
) = reason
|
) = reason
|
||||||
{
|
{
|
||||||
let python_version: Range<Version> =
|
let python_version: Range<Version> =
|
||||||
PubGrubSpecifier::from_release_specifiers(&requires_python)?.into();
|
VersionRangesSpecifier::from_release_specifiers(&requires_python)?.into();
|
||||||
|
|
||||||
let package = &self.next;
|
let package = &self.next;
|
||||||
self.pubgrub
|
self.pubgrub
|
||||||
|
|
|
||||||
|
|
@ -773,5 +773,5 @@ pub(crate) enum Error {
|
||||||
Anyhow(#[from] anyhow::Error),
|
Anyhow(#[from] anyhow::Error),
|
||||||
|
|
||||||
#[error(transparent)]
|
#[error(transparent)]
|
||||||
PubGrubSpecifier(#[from] uv_resolver::PubGrubSpecifierError),
|
VersionRangesSpecifier(#[from] uv_pep440::VersionRangesSpecifierError),
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue