diff --git a/crates/uv-distribution-filename/src/lib.rs b/crates/uv-distribution-filename/src/lib.rs index 8ff34faff..95d0a98ae 100644 --- a/crates/uv-distribution-filename/src/lib.rs +++ b/crates/uv-distribution-filename/src/lib.rs @@ -101,7 +101,6 @@ mod tests { #[test] fn wheel_filename_size() { - // TODO(konsti): Move the variant to the tag so this type remains small - assert_eq!(size_of::(), 72); + assert_eq!(size_of::(), 48); } } diff --git a/crates/uv-distribution-filename/src/snapshots/uv_distribution_filename__wheel__tests__ok_build_tag.snap b/crates/uv-distribution-filename/src/snapshots/uv_distribution_filename__wheel__tests__ok_build_tag.snap index 88028e137..950e69f12 100644 --- a/crates/uv-distribution-filename/src/snapshots/uv_distribution_filename__wheel__tests__ok_build_tag.snap +++ b/crates/uv-distribution-filename/src/snapshots/uv_distribution_filename__wheel__tests__ok_build_tag.snap @@ -1,7 +1,6 @@ --- source: crates/uv-distribution-filename/src/wheel.rs expression: "WheelFilename::from_str(\"foo-1.2.3-202206090410-py3-none-any.whl\")" -snapshot_kind: text --- Ok( WheelFilename { @@ -29,9 +28,9 @@ Ok( platform_tag: [ Any, ], + variant: None, repr: "202206090410-py3-none-any", }, }, - variant: None, }, ) diff --git a/crates/uv-distribution-filename/src/snapshots/uv_distribution_filename__wheel__tests__ok_multiple_tags.snap b/crates/uv-distribution-filename/src/snapshots/uv_distribution_filename__wheel__tests__ok_multiple_tags.snap index 030b6d484..9e0afcd9b 100644 --- a/crates/uv-distribution-filename/src/snapshots/uv_distribution_filename__wheel__tests__ok_multiple_tags.snap +++ b/crates/uv-distribution-filename/src/snapshots/uv_distribution_filename__wheel__tests__ok_multiple_tags.snap @@ -1,7 +1,6 @@ --- source: crates/uv-distribution-filename/src/wheel.rs expression: "WheelFilename::from_str(\"foo-1.2.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl\")" -snapshot_kind: text --- Ok( WheelFilename { @@ -39,9 +38,9 @@ Ok( arch: X86_64, }, ], + variant: None, repr: "cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64", }, }, - variant: None, }, ) diff --git a/crates/uv-distribution-filename/src/snapshots/uv_distribution_filename__wheel__tests__ok_single_tags.snap b/crates/uv-distribution-filename/src/snapshots/uv_distribution_filename__wheel__tests__ok_single_tags.snap index 1b0a0e384..fb6f0ab2d 100644 --- a/crates/uv-distribution-filename/src/snapshots/uv_distribution_filename__wheel__tests__ok_single_tags.snap +++ b/crates/uv-distribution-filename/src/snapshots/uv_distribution_filename__wheel__tests__ok_single_tags.snap @@ -1,7 +1,6 @@ --- source: crates/uv-distribution-filename/src/wheel.rs expression: "WheelFilename::from_str(\"foo-1.2.3-py3-none-any.whl\")" -snapshot_kind: text --- Ok( WheelFilename { @@ -19,6 +18,5 @@ Ok( platform_tag: Any, }, }, - variant: None, }, ) diff --git a/crates/uv-distribution-filename/src/snapshots/uv_distribution_filename__wheel__tests__ok_variant_tag-2.snap b/crates/uv-distribution-filename/src/snapshots/uv_distribution_filename__wheel__tests__ok_variant_tag-2.snap index 7f1e19e3a..30686890f 100644 --- a/crates/uv-distribution-filename/src/snapshots/uv_distribution_filename__wheel__tests__ok_variant_tag-2.snap +++ b/crates/uv-distribution-filename/src/snapshots/uv_distribution_filename__wheel__tests__ok_variant_tag-2.snap @@ -1,7 +1,6 @@ --- source: crates/uv-distribution-filename/src/wheel.rs expression: "WheelFilename::from_str(\"dummy_project-0.0.1-1234-py3-none-any-36266d4d.whl\")" -snapshot_kind: text --- Ok( WheelFilename { @@ -29,11 +28,11 @@ Ok( platform_tag: [ Any, ], + variant: Some( + "36266d4d", + ), repr: "1234-py3-none-any-36266d4d", }, }, - variant: Some( - "36266d4d", - ), }, ) diff --git a/crates/uv-distribution-filename/src/snapshots/uv_distribution_filename__wheel__tests__ok_variant_tag.snap b/crates/uv-distribution-filename/src/snapshots/uv_distribution_filename__wheel__tests__ok_variant_tag.snap index 010aa840f..b44fe4567 100644 --- a/crates/uv-distribution-filename/src/snapshots/uv_distribution_filename__wheel__tests__ok_variant_tag.snap +++ b/crates/uv-distribution-filename/src/snapshots/uv_distribution_filename__wheel__tests__ok_variant_tag.snap @@ -1,7 +1,6 @@ --- source: crates/uv-distribution-filename/src/wheel.rs expression: "WheelFilename::from_str(\"dummy_project-0.0.1-py3-none-any-36266d4d.whl\")" -snapshot_kind: text --- Ok( WheelFilename { @@ -24,11 +23,11 @@ Ok( platform_tag: [ Any, ], + variant: Some( + "36266d4d", + ), repr: "py3-none-any-36266d4d", }, }, - variant: Some( - "36266d4d", - ), }, ) diff --git a/crates/uv-distribution-filename/src/wheel.rs b/crates/uv-distribution-filename/src/wheel.rs index daab2e51d..3efa555b0 100644 --- a/crates/uv-distribution-filename/src/wheel.rs +++ b/crates/uv-distribution-filename/src/wheel.rs @@ -6,9 +6,6 @@ use memchr::memchr; use serde::{Deserialize, Deserializer, Serialize, Serializer, de}; use thiserror::Error; -use crate::splitter::MemchrSplitter; -use crate::wheel_tag::{WheelTag, WheelTagLarge, WheelTagSmall}; -use crate::{BuildTag, BuildTagError}; use uv_cache_key::cache_digest; use uv_normalize::{InvalidNameError, PackageName}; use uv_pep440::{Version, VersionParseError}; @@ -16,6 +13,11 @@ use uv_platform_tags::{ AbiTag, LanguageTag, ParseAbiTagError, ParseLanguageTagError, ParsePlatformTagError, PlatformTag, TagCompatibility, Tags, }; +use uv_small_str::SmallString; + +use crate::splitter::MemchrSplitter; +use crate::wheel_tag::{WheelTag, WheelTagLarge, WheelTagSmall}; +use crate::{BuildTag, BuildTagError}; #[derive( Debug, @@ -34,7 +36,6 @@ pub struct WheelFilename { pub name: PackageName, pub version: Version, tags: WheelTag, - variant: Option, } impl FromStr for WheelFilename { @@ -75,7 +76,6 @@ impl WheelFilename { Self { name, version, - variant: None, tags: WheelTag::Small { small: WheelTagSmall { python_tag, @@ -98,22 +98,12 @@ impl WheelFilename { /// The wheel filename without the extension. pub fn stem(&self) -> String { - if let Some(variant) = &self.variant { - format!( - "{}-{}-{}-{}", - self.name.as_dist_info_name(), - self.version, - self.tags, - variant - ) - } else { - format!( - "{}-{}-{}", - self.name.as_dist_info_name(), - self.version, - self.tags - ) - } + format!( + "{}-{}-{}", + self.name.as_dist_info_name(), + self.version, + self.tags + ) } /// Returns a consistent cache key with a maximum length of 64 characters. @@ -123,12 +113,7 @@ impl WheelFilename { pub fn cache_key(&self) -> String { const CACHE_KEY_MAX_LEN: usize = 64; - // Include variant in the cache key if it exists - let full = if let Some(variant) = &self.variant { - format!("{}-{}-{}", self.version, self.tags, variant) - } else { - format!("{}-{}", self.version, self.tags) - }; + let full = format!("{}-{}", self.version, self.tags); if full.len() <= CACHE_KEY_MAX_LEN { return full; @@ -136,11 +121,7 @@ impl WheelFilename { // Create a digest of the tag string (and variant if it exists) to retain // compatibility across platforms, Rust versions, etc. - let digest = if let Some(variant) = &self.variant { - cache_digest(&format!("{}-{}", self.tags, variant)) - } else { - cache_digest(&format!("{}", self.tags)) - }; + let digest = cache_digest(&format!("{}", self.tags)); // Truncate the version, but avoid trailing dots, plus signs, etc. to avoid ambiguity. let version_width = CACHE_KEY_MAX_LEN - 1 /* dash */ - 16 /* digest */; @@ -155,7 +136,10 @@ impl WheelFilename { /// Return the wheel's variant tag, if present. pub fn variant(&self) -> Option<&str> { - self.variant.as_deref() + match &self.tags { + WheelTag::Small { .. } => None, + WheelTag::Large { large } => large.variant.as_deref(), + } } /// Return the wheel's Python tags. @@ -244,7 +228,7 @@ impl WheelFilename { // Extract variant from filenames with the format, e.g., `ml_project-0.0.1-py3-none-any-cu128.whl`. // TODO(charlie): Integrate this into the filename parsing; it's just easier to do it upfront // for now. - // 7 components: We have both a build tag and a variant_tag + // 7 components: We have both a build tag and a variant tag. if let Some(variant_tag) = splitter.next() { if splitter.next().is_some() { return Err(WheelFilenameError::InvalidWheelFileName( @@ -264,7 +248,7 @@ impl WheelFilename { false, ) } else { - // 6 components: Check whether we have a build tag or variant tag + // 6 components: Determine whether we have a build tag or a variant tag. if LanguageTag::from_str( &stem[build_tag_or_python_tag + 1..python_tag_or_abi_tag], ) @@ -278,7 +262,7 @@ impl WheelFilename { &stem[python_tag_or_abi_tag + 1..abi_tag_or_platform_tag], &stem[abi_tag_or_platform_tag + 1..platform_tag], Some(&stem[platform_tag + 1..]), - // Always take the slow path if a build tag is present. + // Always take the slow path if a variant tag is present. false, ) } else { @@ -351,6 +335,7 @@ impl WheelFilename { .map(PlatformTag::from_str) .filter_map(Result::ok) .collect(), + variant: variant.map(SmallString::from), repr: repr.into(), }), } @@ -360,7 +345,6 @@ impl WheelFilename { name, version, tags, - variant: variant.map(ToString::to_string), }) } } @@ -563,6 +547,6 @@ mod tests { // Variant tags should be included in the cache key. let filename = WheelFilename::from_str("dummy_project-0.0.1-py3-none-any-36266d4d.whl").unwrap(); - insta::assert_snapshot!(filename.cache_key(), @"0.0.1-py3-none-any-36266d4d-36266d4d"); + insta::assert_snapshot!(filename.cache_key(), @"0.0.1-py3-none-any-36266d4d"); } } diff --git a/crates/uv-distribution-filename/src/wheel_tag.rs b/crates/uv-distribution-filename/src/wheel_tag.rs index 0315e8372..4afe8f00d 100644 --- a/crates/uv-distribution-filename/src/wheel_tag.rs +++ b/crates/uv-distribution-filename/src/wheel_tag.rs @@ -102,6 +102,8 @@ pub(crate) struct WheelTagLarge { pub(crate) abi_tag: TagSet, /// The platform tag(s), e.g., `none` in `1.2.3-73-py3-none-any`. pub(crate) platform_tag: TagSet, + /// The optional variant tag. + pub(crate) variant: Option, /// The string representation of the tag. /// /// Preserves any unsupported tags that were filtered out when parsing the wheel filename.