From a5372d4e4dd6e82ce7fd1bf80805601dba6536c0 Mon Sep 17 00:00:00 2001 From: Charlie Marsh Date: Mon, 19 Feb 2024 22:26:29 -0500 Subject: [PATCH] Ignore invalid extras from PyPI (#1731) ## Summary We don't control these, so it seems preferable _not_ to fail on them, but rather, to just ignore them entirely. (I considered adding a long allow-list, but then questioned the point of it? We'd end up having to extend it if more invalid extras were published in the future.) Closes https://github.com/astral-sh/uv/issues/1633. --- crates/pypi-types/src/lenient_requirement.rs | 31 -------------------- crates/pypi-types/src/metadata.rs | 15 ++++++---- 2 files changed, 9 insertions(+), 37 deletions(-) diff --git a/crates/pypi-types/src/lenient_requirement.rs b/crates/pypi-types/src/lenient_requirement.rs index 2564a3ee9..616e6a905 100644 --- a/crates/pypi-types/src/lenient_requirement.rs +++ b/crates/pypi-types/src/lenient_requirement.rs @@ -7,7 +7,6 @@ use tracing::warn; use pep440_rs::{VersionSpecifiers, VersionSpecifiersParseError}; use pep508_rs::{Pep508Error, Requirement}; -use uv_normalize::{ExtraName, InvalidNameError}; /// Ex) `>=7.2.0<8.0.0` static MISSING_COMMA: Lazy = Lazy::new(|| Regex::new(r"(\d)([<>=~^!])").unwrap()); @@ -123,36 +122,6 @@ impl<'de> Deserialize<'de> for LenientVersionSpecifiers { } } -#[derive(Debug, Clone)] -pub struct LenientExtraName(ExtraName); - -impl LenientExtraName { - /// Parse an [`ExtraName`] from a string, but return `None` if the name is `.none`. - /// - /// Some versions of `flit` erroneously included `.none` as an extra name, which is not - /// allowed by PEP 508. - /// - /// See: - pub fn try_parse(name: String) -> Option> { - match ExtraName::new(name) { - Ok(name) => Some(Ok(Self(name))), - Err(err) => { - if err.as_str() == ".none" { - None - } else { - Some(Err(err)) - } - } - } - } -} - -impl From for ExtraName { - fn from(name: LenientExtraName) -> Self { - name.0 - } -} - #[cfg(test)] mod tests { use std::str::FromStr; diff --git a/crates/pypi-types/src/metadata.rs b/crates/pypi-types/src/metadata.rs index f82662d0d..bfe2d6e22 100644 --- a/crates/pypi-types/src/metadata.rs +++ b/crates/pypi-types/src/metadata.rs @@ -6,13 +6,14 @@ use std::str::FromStr; use mailparse::{MailHeaderMap, MailParseError}; use serde::{Deserialize, Serialize}; use thiserror::Error; +use tracing::warn; use pep440_rs::{Version, VersionParseError, VersionSpecifiers, VersionSpecifiersParseError}; use pep508_rs::{Pep508Error, Requirement}; use uv_normalize::{ExtraName, InvalidNameError, PackageName}; use crate::lenient_requirement::LenientRequirement; -use crate::{LenientExtraName, LenientVersionSpecifiers}; +use crate::LenientVersionSpecifiers; /// Python Package Metadata 2.1 as specified in /// . @@ -119,12 +120,14 @@ impl Metadata21 { }) .transpose()?; let provides_extras = get_all_values("Provides-Extra") - .filter_map(LenientExtraName::try_parse) - .map(|result| match result { - Ok(extra_name) => Ok(ExtraName::from(extra_name)), - Err(err) => Err(err), + .filter_map(|provides_extra| match ExtraName::new(provides_extra) { + Ok(extra_name) => Some(extra_name), + Err(err) => { + warn!("Ignoring invalid extra: {err}"); + None + } }) - .collect::, _>>()?; + .collect::>(); Ok(Metadata21 { metadata_version,