diff --git a/crates/pypi-types/src/lenient_requirement.rs b/crates/pypi-types/src/lenient_requirement.rs index e999ab05f..7a8820ba0 100644 --- a/crates/pypi-types/src/lenient_requirement.rs +++ b/crates/pypi-types/src/lenient_requirement.rs @@ -23,6 +23,9 @@ static TRAILING_COMMA: Lazy = Lazy::new(|| Regex::new(r",\s*$").unwrap()) static STRAY_QUOTES: Lazy = Lazy::new(|| Regex::new(r#"['"]([*\d])|([*\d])['"]"#).unwrap()); /// Ex) `>dev` static GREATER_THAN_DEV: Lazy = Lazy::new(|| Regex::new(r">dev").unwrap()); +/// Ex) `>=9.0.0a1.0` +static TRAILING_ZERO: Lazy = + Lazy::new(|| Regex::new(r"(\d+(\.\d)*(a|b|rc|post|dev)\d+)\.0").unwrap()); /// Regex to match the invalid specifier, replacement to fix it and message about was wrong and /// fixed @@ -49,6 +52,8 @@ static FIXUPS: &[(&Lazy, &str, &str)] = &[ (&STRAY_QUOTES, r"$1$2", "removing stray quotes"), // Given `>dev`, rewrite to `>0.0.0dev` (&GREATER_THAN_DEV, r">0.0.0dev", "assuming 0.0.0dev"), + // Given `>=9.0.0a1.0`, rewrite to `>=9.0.0a1` + (&TRAILING_ZERO, r"${1}", "removing trailing zero"), ]; fn parse_with_fixups>(input: &str, type_name: &str) -> Result { @@ -334,4 +339,26 @@ mod tests { let expected: VersionSpecifiers = VersionSpecifiers::from_str(">0.0.0dev").unwrap(); assert_eq!(actual, expected); } + + /// + #[test] + fn trailing_alpha_zero() { + let actual: VersionSpecifiers = LenientVersionSpecifiers::from_str(">=9.0.0a1.0") + .unwrap() + .into(); + let expected: VersionSpecifiers = VersionSpecifiers::from_str(">=9.0.0a1").unwrap(); + assert_eq!(actual, expected); + + let actual: VersionSpecifiers = LenientVersionSpecifiers::from_str(">=9.0a1.0") + .unwrap() + .into(); + let expected: VersionSpecifiers = VersionSpecifiers::from_str(">=9.0a1").unwrap(); + assert_eq!(actual, expected); + + let actual: VersionSpecifiers = LenientVersionSpecifiers::from_str(">=9a1.0") + .unwrap() + .into(); + let expected: VersionSpecifiers = VersionSpecifiers::from_str(">=9a1").unwrap(); + assert_eq!(actual, expected); + } }