Skip to content

Commit

Permalink
Use structured wheel tags everywhere (astral-sh#10542)
Browse files Browse the repository at this point in the history
## Summary

This PR extends the thinking in astral-sh#10525 to platform tags, and then uses
the structured tag enums everywhere, rather than passing around strings.
I think this is a big improvement! It means we're no longer doing ad hoc
tag parsing all over the place.
  • Loading branch information
charliermarsh authored Jan 14, 2025
1 parent 2ffa319 commit 5c91217
Show file tree
Hide file tree
Showing 33 changed files with 1,617 additions and 480 deletions.
15 changes: 10 additions & 5 deletions Cargo.lock

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

24 changes: 19 additions & 5 deletions crates/uv-bench/benches/distribution_filename.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
use std::str::FromStr;

use uv_bench::criterion::{
criterion_group, criterion_main, measurement::WallTime, BenchmarkId, Criterion, Throughput,
};
use uv_distribution_filename::WheelFilename;
use uv_platform_tags::Tags;
use uv_platform_tags::{AbiTag, LanguageTag, PlatformTag, Tags};

/// A set of platform tags extracted from burntsushi's Archlinux workstation.
/// We could just re-create these via `Tags::from_env`, but those might differ
Expand Down Expand Up @@ -73,9 +75,15 @@ const INVALID_WHEEL_NAMES: &[(&str, &str)] = &[
/// extra processing. We thus expect construction to become slower, but we
/// write a benchmark to ensure it is still "reasonable."
fn benchmark_build_platform_tags(c: &mut Criterion<WallTime>) {
let tags: Vec<(String, String, String)> = PLATFORM_TAGS
let tags: Vec<(LanguageTag, AbiTag, PlatformTag)> = PLATFORM_TAGS
.iter()
.map(|&(py, abi, plat)| (py.to_string(), abi.to_string(), plat.to_string()))
.map(|&(py, abi, plat)| {
(
LanguageTag::from_str(py).unwrap(),
AbiTag::from_str(abi).unwrap(),
PlatformTag::from_str(plat).unwrap(),
)
})
.collect();

let mut group = c.benchmark_group("build_platform_tags");
Expand Down Expand Up @@ -132,9 +140,15 @@ fn benchmark_wheelname_parsing_failure(c: &mut Criterion<WallTime>) {
/// implementation did an exhaustive search over each of them for each tag in
/// the wheel filename.
fn benchmark_wheelname_tag_compatibility(c: &mut Criterion<WallTime>) {
let tags: Vec<(String, String, String)> = PLATFORM_TAGS
let tags: Vec<(LanguageTag, AbiTag, PlatformTag)> = PLATFORM_TAGS
.iter()
.map(|&(py, abi, plat)| (py.to_string(), abi.to_string(), plat.to_string()))
.map(|&(py, abi, plat)| {
(
LanguageTag::from_str(py).unwrap(),
AbiTag::from_str(abi).unwrap(),
PlatformTag::from_str(plat).unwrap(),
)
})
.collect();
let tags = Tags::new(tags);

Expand Down
1 change: 1 addition & 0 deletions crates/uv-build-backend/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ uv-globfilter = { workspace = true }
uv-normalize = { workspace = true }
uv-pep440 = { workspace = true }
uv-pep508 = { workspace = true }
uv-platform-tags = { workspace = true }
uv-pypi-types = { workspace = true }
uv-version = { workspace = true }
uv-warnings = { workspace = true }
Expand Down
72 changes: 49 additions & 23 deletions crates/uv-build-backend/src/wheel.rs
Original file line number Diff line number Diff line change
@@ -1,19 +1,23 @@
use crate::metadata::{BuildBackendSettings, DEFAULT_EXCLUDES};
use crate::{DirectoryWriter, Error, FileList, ListWriter, PyProjectToml};
use std::io::{BufReader, Read, Write};
use std::path::{Path, PathBuf};
use std::{io, mem};

use fs_err::File;
use globset::{GlobSet, GlobSetBuilder};
use itertools::Itertools;
use sha2::{Digest, Sha256};
use std::io::{BufReader, Read, Write};
use std::path::{Path, PathBuf};
use std::{io, mem};
use tracing::{debug, trace};
use uv_distribution_filename::WheelFilename;
use walkdir::WalkDir;
use zip::{CompressionMethod, ZipWriter};

use uv_distribution_filename::{TagSet, WheelFilename};
use uv_fs::Simplified;
use uv_globfilter::{parse_portable_glob, GlobDirFilter};
use uv_platform_tags::{AbiTag, LanguageTag, PlatformTag};
use uv_warnings::warn_user_once;
use walkdir::WalkDir;
use zip::{CompressionMethod, ZipWriter};

use crate::metadata::{BuildBackendSettings, DEFAULT_EXCLUDES};
use crate::{DirectoryWriter, Error, FileList, ListWriter, PyProjectToml};

/// Build a wheel from the source tree and place it in the output directory.
pub fn build_wheel(
Expand All @@ -33,9 +37,12 @@ pub fn build_wheel(
name: pyproject_toml.name().clone(),
version: pyproject_toml.version().clone(),
build_tag: None,
python_tag: vec!["py3".to_string()],
abi_tag: vec!["none".to_string()],
platform_tag: vec!["any".to_string()],
python_tag: TagSet::from_slice(&[LanguageTag::Python {
major: 3,
minor: None,
}]),
abi_tag: TagSet::from_buf([AbiTag::None]),
platform_tag: TagSet::from_buf([PlatformTag::Any]),
};

let wheel_path = wheel_dir.join(filename.to_string());
Expand Down Expand Up @@ -68,9 +75,12 @@ pub fn list_wheel(
name: pyproject_toml.name().clone(),
version: pyproject_toml.version().clone(),
build_tag: None,
python_tag: vec!["py3".to_string()],
abi_tag: vec!["none".to_string()],
platform_tag: vec!["any".to_string()],
python_tag: TagSet::from_slice(&[LanguageTag::Python {
major: 3,
minor: None,
}]),
abi_tag: TagSet::from_buf([AbiTag::None]),
platform_tag: TagSet::from_buf([PlatformTag::Any]),
};

let mut files = FileList::new();
Expand Down Expand Up @@ -247,9 +257,12 @@ pub fn build_editable(
name: pyproject_toml.name().clone(),
version: pyproject_toml.version().clone(),
build_tag: None,
python_tag: vec!["py3".to_string()],
abi_tag: vec!["none".to_string()],
platform_tag: vec!["any".to_string()],
python_tag: TagSet::from_slice(&[LanguageTag::Python {
major: 3,
minor: None,
}]),
abi_tag: TagSet::from_buf([AbiTag::None]),
platform_tag: TagSet::from_buf([PlatformTag::Any]),
};

let wheel_path = wheel_dir.join(filename.to_string());
Expand Down Expand Up @@ -299,9 +312,12 @@ pub fn metadata(
name: pyproject_toml.name().clone(),
version: pyproject_toml.version().clone(),
build_tag: None,
python_tag: vec!["py3".to_string()],
abi_tag: vec!["none".to_string()],
platform_tag: vec!["any".to_string()],
python_tag: TagSet::from_slice(&[LanguageTag::Python {
major: 3,
minor: None,
}]),
abi_tag: TagSet::from_buf([AbiTag::None]),
platform_tag: TagSet::from_buf([PlatformTag::Any]),
};

debug!(
Expand Down Expand Up @@ -744,6 +760,7 @@ mod test {
use uv_fs::Simplified;
use uv_normalize::PackageName;
use uv_pep440::Version;
use uv_platform_tags::{AbiTag, PlatformTag};
use walkdir::WalkDir;

#[test]
Expand All @@ -752,9 +769,18 @@ mod test {
name: PackageName::from_str("foo").unwrap(),
version: Version::from_str("1.2.3").unwrap(),
build_tag: None,
python_tag: vec!["py2".to_string(), "py3".to_string()],
abi_tag: vec!["none".to_string()],
platform_tag: vec!["any".to_string()],
python_tag: TagSet::from_slice(&[
LanguageTag::Python {
major: 2,
minor: None,
},
LanguageTag::Python {
major: 3,
minor: None,
},
]),
abi_tag: TagSet::from_buf([AbiTag::None]),
platform_tag: TagSet::from_buf([PlatformTag::Any]),
};

assert_snapshot!(wheel_info(&filename, "1.0.0+test"), @r"
Expand Down
2 changes: 1 addition & 1 deletion crates/uv-cache/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -787,7 +787,7 @@ impl CacheBucket {
Self::Interpreter => "interpreter-v4",
// Note that when bumping this, you'll also need to bump it
// in crates/uv/tests/cache_clean.rs.
Self::Simple => "simple-v14",
Self::Simple => "simple-v15",
// Note that when bumping this, you'll also need to bump it
// in crates/uv/tests/cache_prune.rs.
Self::Wheels => "wheels-v3",
Expand Down
3 changes: 2 additions & 1 deletion crates/uv-distribution-filename/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,9 @@ uv-normalize = { workspace = true }
uv-pep440 = { workspace = true }
uv-platform-tags = { workspace = true }

rkyv = { workspace = true }
rkyv = { workspace = true, features = ["smallvec-1"] }
serde = { workspace = true }
smallvec = { workspace = true }
thiserror = { workspace = true }
url = { workspace = true }

Expand Down
2 changes: 1 addition & 1 deletion crates/uv-distribution-filename/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ pub use build_tag::{BuildTag, BuildTagError};
pub use egg::{EggInfoFilename, EggInfoFilenameError};
pub use extension::{DistExtension, ExtensionError, SourceDistExtension};
pub use source_dist::{SourceDistFilename, SourceDistFilenameError};
pub use wheel::{WheelFilename, WheelFilenameError};
pub use wheel::{TagSet, WheelFilename, WheelFilenameError};

mod build_tag;
mod egg;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
source: crates/uv-distribution-filename/src/wheel.rs
expression: "WheelFilename::from_str(\"foo-1.2.3-202206090410-python-abi-platform.whl\")"
expression: "WheelFilename::from_str(\"foo-1.2.3-202206090410-py3-none-any.whl\")"
---
Ok(
WheelFilename {
Expand All @@ -15,13 +15,16 @@ Ok(
),
),
python_tag: [
"python",
Python {
major: 3,
minor: None,
},
],
abi_tag: [
"abi",
None,
],
platform_tag: [
"platform",
Any,
],
},
)
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
source: crates/uv-distribution-filename/src/wheel.rs
expression: "WheelFilename::from_str(\"foo-1.2.3-ab.cd.ef-gh-ij.kl.mn.op.qr.st.whl\")"
expression: "WheelFilename::from_str(\"foo-1.2.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl\")"
---
Ok(
WheelFilename {
Expand All @@ -10,20 +10,31 @@ Ok(
version: "1.2.3",
build_tag: None,
python_tag: [
"ab",
"cd",
"ef",
CPython {
python_version: (
3,
11,
),
},
],
abi_tag: [
"gh",
CPython {
gil_disabled: false,
python_version: (
3,
11,
),
},
],
platform_tag: [
"ij",
"kl",
"mn",
"op",
"qr",
"st",
Manylinux {
major: 2,
minor: 17,
arch: X86_64,
},
Manylinux2014 {
arch: X86_64,
},
],
},
)
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
source: crates/uv-distribution-filename/src/wheel.rs
expression: "WheelFilename::from_str(\"foo-1.2.3-foo-bar-baz.whl\")"
expression: "WheelFilename::from_str(\"foo-1.2.3-py3-none-any.whl\")"
---
Ok(
WheelFilename {
Expand All @@ -10,13 +10,16 @@ Ok(
version: "1.2.3",
build_tag: None,
python_tag: [
"foo",
Python {
major: 3,
minor: None,
},
],
abi_tag: [
"bar",
None,
],
platform_tag: [
"baz",
Any,
],
},
)
Loading

0 comments on commit 5c91217

Please sign in to comment.