From c883b123ac78a9eb86afb85a0f37f46a770d1964 Mon Sep 17 00:00:00 2001 From: konsti Date: Tue, 7 Nov 2023 12:37:23 +0100 Subject: [PATCH] Allow greater than star (`torch (>=1.9.*)`) in lenient requirement (#351) This appeared in the pypi top 8k testing. --- crates/pypi-types/src/metadata.rs | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/crates/pypi-types/src/metadata.rs b/crates/pypi-types/src/metadata.rs index b2290b5bf..e4d7258c4 100644 --- a/crates/pypi-types/src/metadata.rs +++ b/crates/pypi-types/src/metadata.rs @@ -211,8 +211,9 @@ impl Metadata21 { } static MISSING_COMMA: Lazy = Lazy::new(|| Regex::new(r"(\d)([<>=~^!])").unwrap()); - static NOT_EQUAL_TILDE: Lazy = Lazy::new(|| Regex::new(r"!=~((?:\d\.)*\d)").unwrap()); +/// e.g. `>=1.9.*` +static GREATER_THAN_STAR: Lazy = Lazy::new(|| Regex::new(r">=(\d+\.\d+)\.\*").unwrap()); /// Like [`Requirement`], but attempts to correct some common errors in user-provided requirements. #[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq)] @@ -247,6 +248,17 @@ impl FromStr for LenientRequirement { } } + // Given `torch (>=1.9.*)`, rewrite to `torch (>=1.9)` + let patched = GREATER_THAN_STAR.replace(s, r">=${1}"); + if patched != s { + if let Ok(requirement) = Requirement::from_str(&patched) { + warn!( + "Removing star after greater equal operator (before: `{s}`; after: `{patched}`)", + ); + return Ok(Self(requirement)); + } + } + Err(err) } } @@ -339,4 +351,13 @@ mod tests { let expected: Requirement = Requirement::from_str("jupyter-core (!=5.*,>=4.12)").unwrap(); assert_eq!(actual, expected); } + + #[test] + fn greater_than_star() { + let actual: Requirement = LenientRequirement::from_str("torch (>=1.9.*)") + .unwrap() + .into(); + let expected: Requirement = Requirement::from_str("torch (>=1.9)").unwrap(); + assert_eq!(actual, expected); + } }