Skip to content

Commit

Permalink
Shrink tags
Browse files Browse the repository at this point in the history
  • Loading branch information
charliermarsh committed Jan 12, 2025
1 parent 6b4b12d commit 4633b58
Show file tree
Hide file tree
Showing 4 changed files with 76 additions and 151 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions crates/uv-platform-tags/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ doctest = false
workspace = true

[dependencies]
uv-small-str = { workspace = true }

memchr = { workspace = true }
rkyv = { workspace = true}
rustc-hash = { workspace = true }
Expand Down
176 changes: 40 additions & 136 deletions crates/uv-platform-tags/src/platform_tag.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,18 @@
use std::fmt::Formatter;
use std::str::FromStr;

use uv_small_str::SmallString;

use crate::{Arch, BinaryFormat};

/// A tag to represent the platform compatibility of a Python distribution.
///
/// This is the third segment in the wheel filename, following the language and ABI tags. For
/// example, in `cp39-none-manylinux_2_24_x86_64.whl`, the platform tag is `manylinux_2_24_x86_64`.
///
/// For simplicity (and to reduce struct size), the non-Linux, macOS, and Windows variants (like
/// FreeBSD) store an opaque suffix, which combines the release (like `3.14`) and architecture (like
/// `x86_64`) into a single string (like `3_14_x86_64`).
#[derive(
Debug,
Clone,
Expand Down Expand Up @@ -50,19 +56,19 @@ pub enum PlatformTag {
/// Ex) `android_21_x86_64`
Android { api_level: u16, arch: Arch },
/// Ex) `freebsd_12_x86_64`
FreeBsd { release: String, arch: Arch },
FreeBsd { release_arch: SmallString },
/// Ex) `netbsd_9_x86_64`
NetBsd { release: String, arch: Arch },
NetBsd { release_arch: SmallString },
/// Ex) `openbsd_6_x86_64`
OpenBsd { release: String, arch: Arch },
OpenBsd { release_arch: SmallString },
/// Ex) `dragonfly_6_x86_64`
Dragonfly { release: String, arch: Arch },
Dragonfly { release_arch: SmallString },
/// Ex) `haiku_1_x86_64`
Haiku { release: String, arch: Arch },
Haiku { release_arch: SmallString },
/// Ex) `illumos_5_11_x86_64`
Illumos { release: String, arch: String },
Illumos { release_arch: SmallString },
/// Ex) `solaris_11_4_x86_64`
Solaris { release: String, arch: String },
Solaris { release_arch: SmallString },
}

impl PlatformTag {
Expand Down Expand Up @@ -124,13 +130,13 @@ impl std::fmt::Display for PlatformTag {
Self::WinAmd64 => write!(f, "win_amd64"),
Self::WinArm64 => write!(f, "win_arm64"),
Self::Android { api_level, arch } => write!(f, "android_{api_level}_{arch}"),
Self::FreeBsd { release, arch } => write!(f, "freebsd_{release}_{arch}"),
Self::NetBsd { release, arch } => write!(f, "netbsd_{release}_{arch}"),
Self::OpenBsd { release, arch } => write!(f, "openbsd_{release}_{arch}"),
Self::Dragonfly { release, arch } => write!(f, "dragonfly_{release}_{arch}"),
Self::Haiku { release, arch } => write!(f, "haiku_{release}_{arch}"),
Self::Illumos { release, arch } => write!(f, "illumos_{release}_{arch}"),
Self::Solaris { release, arch } => write!(f, "solaris_{release}_{arch}_64bit"),
Self::FreeBsd { release_arch } => write!(f, "freebsd_{release_arch}"),
Self::NetBsd { release_arch } => write!(f, "netbsd_{release_arch}"),
Self::OpenBsd { release_arch } => write!(f, "openbsd_{release_arch}"),
Self::Dragonfly { release_arch } => write!(f, "dragonfly_{release_arch}"),
Self::Haiku { release_arch } => write!(f, "haiku_{release_arch}"),
Self::Illumos { release_arch } => write!(f, "illumos_{release_arch}"),
Self::Solaris { release_arch } => write!(f, "solaris_{release_arch}_64bit"),
}
}
}
Expand Down Expand Up @@ -386,20 +392,8 @@ impl FromStr for PlatformTag {
});
}

// Try each known Arch value as a potential suffix
for arch in Arch::iter() {
if let Some(release) = rest.strip_suffix(arch.name()) {
// Remove trailing underscore from release
let release = release.strip_suffix('_').unwrap_or(release).to_string();
if !release.is_empty() {
return Ok(Self::FreeBsd { release, arch });
}
}
}

return Err(ParsePlatformTagError::InvalidArch {
platform: "freebsd",
tag: s.to_string(),
return Ok(Self::FreeBsd {
release_arch: SmallString::from(rest),
});
}

Expand All @@ -412,20 +406,8 @@ impl FromStr for PlatformTag {
});
}

// Try each known Arch value as a potential suffix
for arch in Arch::iter() {
if let Some(release) = rest.strip_suffix(arch.name()) {
// Remove trailing underscore from release
let release = release.strip_suffix('_').unwrap_or(release).to_string();
if !release.is_empty() {
return Ok(Self::NetBsd { release, arch });
}
}
}

return Err(ParsePlatformTagError::InvalidArch {
platform: "netbsd",
tag: s.to_string(),
return Ok(Self::NetBsd {
release_arch: SmallString::from(rest),
});
}

Expand All @@ -438,20 +420,8 @@ impl FromStr for PlatformTag {
});
}

// Try each known Arch value as a potential suffix
for arch in Arch::iter() {
if let Some(release) = rest.strip_suffix(arch.name()) {
// Remove trailing underscore from release
let release = release.strip_suffix('_').unwrap_or(release).to_string();
if !release.is_empty() {
return Ok(Self::OpenBsd { release, arch });
}
}
}

return Err(ParsePlatformTagError::InvalidArch {
platform: "openbsd",
tag: s.to_string(),
return Ok(Self::OpenBsd {
release_arch: SmallString::from(rest),
});
}

Expand All @@ -464,20 +434,8 @@ impl FromStr for PlatformTag {
});
}

// Try each known Arch value as a potential suffix
for arch in Arch::iter() {
if let Some(release) = rest.strip_suffix(arch.name()) {
// Remove trailing underscore from release
let release = release.strip_suffix('_').unwrap_or(release).to_string();
if !release.is_empty() {
return Ok(Self::Dragonfly { release, arch });
}
}
}

return Err(ParsePlatformTagError::InvalidArch {
platform: "dragonfly",
tag: s.to_string(),
return Ok(Self::Dragonfly {
release_arch: SmallString::from(rest),
});
}

Expand All @@ -490,20 +448,8 @@ impl FromStr for PlatformTag {
});
}

// Try each known Arch value as a potential suffix
for arch in Arch::iter() {
if let Some(release) = rest.strip_suffix(arch.name()) {
// Remove trailing underscore from release
let release = release.strip_suffix('_').unwrap_or(release).to_string();
if !release.is_empty() {
return Ok(Self::Haiku { release, arch });
}
}
}

return Err(ParsePlatformTagError::InvalidArch {
platform: "haiku",
tag: s.to_string(),
return Ok(Self::Haiku {
release_arch: SmallString::from(rest),
});
}

Expand All @@ -516,23 +462,8 @@ impl FromStr for PlatformTag {
});
}

// Try each known Arch value as a potential suffix
for arch in Arch::iter() {
if let Some(release) = rest.strip_suffix(arch.name()) {
// Remove trailing underscore from release
let release = release.strip_suffix('_').unwrap_or(release).to_string();
if !release.is_empty() {
return Ok(Self::Illumos {
release,
arch: arch.name().to_string(),
});
}
}
}

return Err(ParsePlatformTagError::InvalidArch {
platform: "illumos",
tag: s.to_string(),
return Ok(Self::Illumos {
release_arch: SmallString::from(rest),
});
}

Expand All @@ -545,19 +476,11 @@ impl FromStr for PlatformTag {
});
}

// Try each known Arch value as a potential suffix
for arch in Arch::iter() {
if let Some(rest) = rest.strip_suffix("_64bit") {
if let Some(rest) = rest.strip_suffix(&format!("_{}", arch.name())) {
// Remove trailing underscore from release
let release = rest.strip_suffix('_').unwrap_or(rest).to_string();
if !release.is_empty() {
return Ok(Self::Solaris {
release,
arch: arch.name().to_string(),
});
}
}
if let Some(release_arch) = rest.strip_suffix("_64bit") {
if !release_arch.is_empty() {
return Ok(Self::Solaris {
release_arch: SmallString::from(release_arch),
});
}
}

Expand Down Expand Up @@ -810,50 +733,31 @@ mod tests {
#[test]
fn freebsd_platform() {
let tag = PlatformTag::FreeBsd {
release: "13_14".to_string(),
arch: Arch::X86_64,
release_arch: "13_14_x86_64".into(),
};
assert_eq!(
PlatformTag::from_str("freebsd_13_14_x86_64").as_ref(),
Ok(&tag)
);
assert_eq!(tag.to_string(), "freebsd_13_14_x86_64");

assert_eq!(
PlatformTag::from_str("freebsd_13_14"),
Err(ParsePlatformTagError::InvalidArch {
platform: "freebsd",
tag: "freebsd_13_14".to_string()
})
);
}

#[test]
fn illumos_platform() {
let tag = PlatformTag::Illumos {
release: "5_11".to_string(),
arch: "x86_64".to_string(),
release_arch: "5_11_x86_64".into(),
};
assert_eq!(
PlatformTag::from_str("illumos_5_11_x86_64").as_ref(),
Ok(&tag)
);
assert_eq!(tag.to_string(), "illumos_5_11_x86_64");

assert_eq!(
PlatformTag::from_str("illumos_5_11"),
Err(ParsePlatformTagError::InvalidArch {
platform: "illumos",
tag: "illumos_5_11".to_string()
})
);
}

#[test]
fn solaris_platform() {
let tag = PlatformTag::Solaris {
release: "11_4".to_string(),
arch: "x86_64".to_string(),
release_arch: "11_4_x86_64".into(),
};
assert_eq!(
PlatformTag::from_str("solaris_11_4_x86_64_64bit").as_ref(),
Expand Down
48 changes: 33 additions & 15 deletions crates/uv-platform-tags/src/tags.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@ use std::str::FromStr;
use std::sync::Arc;
use std::{cmp, num::NonZeroU32};

use rustc_hash::FxHashMap;

use crate::abi_tag::AbiTag;
use crate::platform_tag::PlatformTag;
use crate::{Arch, LanguageTag, Os, Platform, PlatformError};
use rustc_hash::FxHashMap;
use uv_small_str::SmallString;

#[derive(Debug, thiserror::Error)]
pub enum TagsError {
Expand Down Expand Up @@ -521,25 +521,40 @@ fn compatible_tags(platform: &Platform) -> Result<Vec<PlatformTag>, PlatformErro
vec![PlatformTag::WinAmd64]
}
(Os::Windows, Arch::Aarch64) => vec![PlatformTag::WinArm64],
(Os::FreeBsd { release }, _) => {
(Os::FreeBsd { release }, arch) => {
let release = release.replace(['.', '-'], "_");
vec![PlatformTag::FreeBsd { release, arch }]
let release_arch = format!("{release}_{arch}");
vec![PlatformTag::FreeBsd {
release_arch: SmallString::from(release_arch),
}]
}
(Os::NetBsd { release }, _) => {
(Os::NetBsd { release }, arch) => {
let release = release.replace(['.', '-'], "_");
vec![PlatformTag::NetBsd { release, arch }]
let release_arch = format!("{release}_{arch}");
vec![PlatformTag::NetBsd {
release_arch: SmallString::from(release_arch),
}]
}
(Os::OpenBsd { release }, _) => {
(Os::OpenBsd { release }, arch) => {
let release = release.replace(['.', '-'], "_");
vec![PlatformTag::OpenBsd { release, arch }]
let release_arch = format!("{release}_{arch}");
vec![PlatformTag::OpenBsd {
release_arch: SmallString::from(release_arch),
}]
}
(Os::Dragonfly { release }, _) => {
(Os::Dragonfly { release }, arch) => {
let release = release.replace(['.', '-'], "_");
vec![PlatformTag::Dragonfly { release, arch }]
let release_arch = format!("{release}_{arch}");
vec![PlatformTag::Dragonfly {
release_arch: SmallString::from(release_arch),
}]
}
(Os::Haiku { release }, _) => {
(Os::Haiku { release }, arch) => {
let release = release.replace(['.', '-'], "_");
vec![PlatformTag::Haiku { release, arch }]
let release_arch = format!("{release}_{arch}");
vec![PlatformTag::Haiku {
release_arch: SmallString::from(release_arch),
}]
}
(Os::Illumos { release, arch }, _) => {
// See https://github.com/python/cpython/blob/46c8d915715aa2bd4d697482aa051fe974d440e1/Lib/sysconfig.py#L722-L730
Expand All @@ -553,13 +568,16 @@ fn compatible_tags(platform: &Platform) -> Result<Vec<PlatformTag>, PlatformErro
// SunOS 5 == Solaris 2
let release = format!("{}_{}", major_ver - 3, other);
let arch = format!("{arch}_64bit");
return Ok(vec![PlatformTag::Solaris { release, arch }]);
let release_arch = format!("{release}_{arch}");
return Ok(vec![PlatformTag::Solaris {
release_arch: SmallString::from(release_arch),
}]);
}
}

let release_arch = format!("{release}_{arch}");
vec![PlatformTag::Illumos {
release: release.to_string(),
arch: arch.to_string(),
release_arch: SmallString::from(release_arch),
}]
}
(Os::Android { api_level }, _) => {
Expand Down

0 comments on commit 4633b58

Please sign in to comment.