From 3e2ae93d6cf977d9bc6ef0953ac3fa6efa1ae25b Mon Sep 17 00:00:00 2001 From: Charlie Marsh Date: Tue, 30 Jul 2024 10:05:54 -0400 Subject: [PATCH] Improve order implementation for Python bound (#5599) ## Summary We shouldn't unequivocally treat exclusions as greater than inclusions... --- crates/uv-resolver/src/requires_python.rs | 32 ++++++++++++++++++++--- 1 file changed, 28 insertions(+), 4 deletions(-) diff --git a/crates/uv-resolver/src/requires_python.rs b/crates/uv-resolver/src/requires_python.rs index f1b3f7d57..fb1217ef1 100644 --- a/crates/uv-resolver/src/requires_python.rs +++ b/crates/uv-resolver/src/requires_python.rs @@ -388,9 +388,10 @@ impl Ord for RequiresPythonBound { fn cmp(&self, other: &Self) -> Ordering { match (self.as_ref(), other.as_ref()) { (Bound::Included(a), Bound::Included(b)) => a.cmp(b), - (Bound::Included(_), Bound::Excluded(_)) => Ordering::Less, - (Bound::Excluded(_), Bound::Included(_)) => Ordering::Greater, + (Bound::Included(a), Bound::Excluded(b)) => a.cmp(b).then(Ordering::Less), + (Bound::Excluded(a), Bound::Included(b)) => a.cmp(b).then(Ordering::Greater), (Bound::Excluded(a), Bound::Excluded(b)) => a.cmp(b), + (Bound::Unbounded, Bound::Unbounded) => Ordering::Equal, (Bound::Unbounded, _) => Ordering::Less, (_, Bound::Unbounded) => Ordering::Greater, } @@ -399,12 +400,14 @@ impl Ord for RequiresPythonBound { #[cfg(test)] mod tests { + use std::cmp::Ordering; + use std::collections::Bound; use std::str::FromStr; use distribution_filename::WheelFilename; - use pep440_rs::VersionSpecifiers; + use pep440_rs::{Version, VersionSpecifiers}; - use crate::RequiresPython; + use crate::{RequiresPython, RequiresPythonBound}; #[test] fn requires_python_included() { @@ -473,4 +476,25 @@ mod tests { ); } } + + #[test] + fn ordering() { + let versions = &[ + // No bound + RequiresPythonBound::new(Bound::Unbounded), + // >=3.8 + RequiresPythonBound::new(Bound::Included(Version::new([3, 8]))), + // >3.8 + RequiresPythonBound::new(Bound::Excluded(Version::new([3, 8]))), + // >=3.8.1 + RequiresPythonBound::new(Bound::Included(Version::new([3, 8, 1]))), + // >3.8.1 + RequiresPythonBound::new(Bound::Excluded(Version::new([3, 8, 1]))), + ]; + for (i, v1) in versions.iter().enumerate() { + for v2 in &versions[i + 1..] { + assert_eq!(v1.cmp(v2), Ordering::Less, "less: {v1:?}\ngreater: {v2:?}",); + } + } + } }