From ad47f40db286496a5860ed8f067313c2e539e020 Mon Sep 17 00:00:00 2001 From: Dev-X25874 <283057883+Dev-X25874@users.noreply.github.com> Date: Sat, 16 May 2026 08:15:05 +0530 Subject: [PATCH 1/2] pep440/version: fix dead "already trimmed" fast-path in only_release_trimmed --- crates/uv-pep440/src/version.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/uv-pep440/src/version.rs b/crates/uv-pep440/src/version.rs index 4faa803b7dbc9..578da6ce5517d 100644 --- a/crates/uv-pep440/src/version.rs +++ b/crates/uv-pep440/src/version.rs @@ -628,7 +628,7 @@ impl Version { #[must_use] pub fn only_release_trimmed(&self) -> Self { if let Some(last_non_zero) = self.release().iter().rposition(|segment| *segment != 0) { - if last_non_zero == self.release().len() { + if last_non_zero + 1 == self.release().len() { // Already trimmed. self.clone() } else { From abd410f68d5e1895c3f1fddc5677e33e31428a1e Mon Sep 17 00:00:00 2001 From: Charlie Marsh Date: Sat, 16 May 2026 06:32:31 +0100 Subject: [PATCH 2/2] Limit to non-pre-release, etc. --- crates/uv-pep440/src/version.rs | 41 +++++++++++++++++++++++++++++++-- 1 file changed, 39 insertions(+), 2 deletions(-) diff --git a/crates/uv-pep440/src/version.rs b/crates/uv-pep440/src/version.rs index 578da6ce5517d..0a78ed0ffb8d9 100644 --- a/crates/uv-pep440/src/version.rs +++ b/crates/uv-pep440/src/version.rs @@ -628,8 +628,16 @@ impl Version { #[must_use] pub fn only_release_trimmed(&self) -> Self { if let Some(last_non_zero) = self.release().iter().rposition(|segment| *segment != 0) { - if last_non_zero + 1 == self.release().len() { - // Already trimmed. + if last_non_zero + 1 == self.release().len() + && self.epoch() == 0 + && self.pre().is_none() + && self.post().is_none() + && self.dev().is_none() + && self.local().is_empty() + && self.min().is_none() + && self.max().is_none() + { + // Already a trimmed release-only version. self.clone() } else { Self::new(self.release().iter().take(last_non_zero + 1).copied()) @@ -4258,6 +4266,35 @@ mod tests { assert_eq!(v2.to_string(), "1.2"); } + #[test] + fn only_release_trimmed_discards_non_release_segments() { + for version in ["1.2a1", "1.2.post1", "1!1.2", "1.2+local", "1.2.dev1"] { + let version = version.parse::().unwrap(); + assert_eq!(version.only_release_trimmed(), Version::new([1, 2])); + } + + assert_eq!( + Version::new([1, 2]) + .with_min(Some(0)) + .only_release_trimmed(), + Version::new([1, 2]) + ); + assert_eq!( + Version::new([1, 2]) + .with_max(Some(0)) + .only_release_trimmed(), + Version::new([1, 2]) + ); + assert_eq!( + Version::new([1, 2, 0]).only_release_trimmed(), + Version::new([1, 2]) + ); + assert_eq!( + Version::new([1, 2]).only_release_trimmed(), + Version::new([1, 2]) + ); + } + #[test] fn type_size() { assert_eq!(size_of::(), size_of::() * 2);