diff --git a/Cargo.lock b/Cargo.lock index eef4d56209a5..1475765d70db 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2674,13 +2674,13 @@ dependencies = [ [[package]] name = "pubgrub" version = "0.2.1" -source = "git+https://github.com/astral-sh/pubgrub?rev=95e1390399cdddee986b658be19587eb1fdb2d79#95e1390399cdddee986b658be19587eb1fdb2d79" +source = "git+https://github.com/astral-sh/pubgrub?rev=57afc831bf2551f164617a10383cf288bf5d190d#57afc831bf2551f164617a10383cf288bf5d190d" dependencies = [ "indexmap", "log", "priority-queue", "rustc-hash", - "thiserror 1.0.67", + "thiserror 2.0.3", "version-ranges", ] @@ -5661,8 +5661,8 @@ checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" [[package]] name = "version-ranges" -version = "0.1.0" -source = "git+https://github.com/astral-sh/pubgrub?rev=95e1390399cdddee986b658be19587eb1fdb2d79#95e1390399cdddee986b658be19587eb1fdb2d79" +version = "0.1.1" +source = "git+https://github.com/astral-sh/pubgrub?rev=57afc831bf2551f164617a10383cf288bf5d190d#57afc831bf2551f164617a10383cf288bf5d190d" dependencies = [ "smallvec", ] diff --git a/Cargo.toml b/Cargo.toml index 0bb72578c0db..3cd2a6c6113a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -130,7 +130,7 @@ petgraph = { version = "0.6.5" } platform-info = { version = "2.0.3" } proc-macro2 = { version = "1.0.86" } procfs = { version = "0.17.0", default-features = false, features = ["flate2"] } -pubgrub = { git = "https://github.com/astral-sh/pubgrub", rev = "95e1390399cdddee986b658be19587eb1fdb2d79" } +pubgrub = { git = "https://github.com/astral-sh/pubgrub", rev = "57afc831bf2551f164617a10383cf288bf5d190d" } quote = { version = "1.0.37" } rayon = { version = "1.10.0" } reflink-copy = { version = "0.1.19" } @@ -175,7 +175,7 @@ unicode-width = { version = "0.1.13" } unscanny = { version = "0.1.0" } url = { version = "2.5.2" } urlencoding = { version = "2.1.3" } -version-ranges = { git = "https://github.com/astral-sh/pubgrub", rev = "95e1390399cdddee986b658be19587eb1fdb2d79" } +version-ranges = { git = "https://github.com/astral-sh/pubgrub", rev = "57afc831bf2551f164617a10383cf288bf5d190d" } walkdir = { version = "2.5.0" } which = { version = "7.0.0", features = ["regex"] } windows-registry = { version = "0.3.0" } diff --git a/crates/uv-pep508/src/marker/algebra.rs b/crates/uv-pep508/src/marker/algebra.rs index a8a1b047b708..2730058c333a 100644 --- a/crates/uv-pep508/src/marker/algebra.rs +++ b/crates/uv-pep508/src/marker/algebra.rs @@ -50,7 +50,7 @@ use std::ops::Bound; use std::sync::Mutex; use std::sync::MutexGuard; -use itertools::Either; +use itertools::{Either, Itertools}; use rustc_hash::FxHashMap; use std::sync::LazyLock; use uv_pep440::{release_specifier_to_range, Operator, Version, VersionSpecifier}; @@ -753,16 +753,15 @@ impl Edges { /// /// Only for use when the `key` is a `PythonVersion`. Normalizes to `PythonFullVersion`. fn from_python_versions(versions: Vec, negated: bool) -> Result { - let mut range = Ranges::empty(); - - // TODO(zanieb): We need to make sure this is performant, repeated unions like this do not - // seem efficient. - for version in versions { - let specifier = VersionSpecifier::equals_version(version.clone()); - let specifier = python_version_to_full_version(specifier)?; - let pubgrub_specifier = release_specifier_to_range(normalize_specifier(specifier)); - range = range.union(&pubgrub_specifier); - } + let mut range: Ranges = versions + .into_iter() + .map(|version| { + let specifier = VersionSpecifier::equals_version(version.clone()); + let specifier = python_version_to_full_version(specifier)?; + Ok(release_specifier_to_range(normalize_specifier(specifier))) + }) + .flatten_ok() + .collect::, NodeId>>()?; if negated { range = range.complement(); @@ -774,14 +773,16 @@ impl Edges { } /// Returns an [`Edges`] where values in the given range are `true`. - fn from_versions(versions: &Vec, negated: bool) -> Edges { - let mut range = Ranges::empty(); - - // TODO(zanieb): We need to make sure this is performant, repeated unions like this do not - // seem efficient. - for version in versions { - range = range.union(&Ranges::singleton(version.clone())); - } + fn from_versions(versions: &[Version], negated: bool) -> Edges { + let mut range: Ranges = versions + .iter() + .map(|version| { + ( + Bound::Included(version.clone()), + Bound::Included(version.clone()), + ) + }) + .collect(); if negated { range = range.complement(); diff --git a/crates/uv-resolver/src/error.rs b/crates/uv-resolver/src/error.rs index b783719dc6c3..86b9e467d9cb 100644 --- a/crates/uv-resolver/src/error.rs +++ b/crates/uv-resolver/src/error.rs @@ -826,13 +826,11 @@ impl<'range> SentinelRange<'range> { } /// Remove local versions sentinels (`+[max]`) from the version ranges. - pub fn strip(&self) -> Ranges { - let mut range = Ranges::empty(); - for (lower, upper) in self.0.iter() { - let (lower, upper) = Self::strip_sentinel(lower.clone(), upper.clone()); - range = range.union(&Range::from_range_bounds((lower, upper))); - } - range + pub fn strip(self) -> Ranges { + self.0 + .iter() + .map(|(lower, upper)| Self::strip_sentinel(lower.clone(), upper.clone())) + .collect() } /// Remove local versions sentinels (`+[max]`) from the interval.