Skip to content

Commit 9146f46

Browse files
committed
.
1 parent 439caa7 commit 9146f46

File tree

28 files changed

+553
-136
lines changed

28 files changed

+553
-136
lines changed

Cargo.lock

Lines changed: 8 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/uv-dispatch/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ uv-pypi-types = { workspace = true }
3333
uv-python = { workspace = true }
3434
uv-resolver = { workspace = true }
3535
uv-types = { workspace = true }
36+
uv-variants = { workspace = true }
3637
uv-variant-frontend = { workspace = true }
3738
uv-version = { workspace = true }
3839
uv-workspace = { workspace = true }

crates/uv-dispatch/src/lib.rs

Lines changed: 23 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ use uv_distribution_types::{
2929
};
3030
use uv_git::GitResolver;
3131
use uv_installer::{Installer, Plan, Planner, Preparer, SitePackages};
32-
use uv_pypi_types::{Conflicts, VariantProviderBackend};
32+
use uv_pypi_types::Conflicts;
3333
use uv_python::{Interpreter, PythonEnvironment};
3434
use uv_resolver::{
3535
ExcludeNewer, FlatIndex, Flexibility, InMemoryIndex, Manifest, OptionsBuilder,
@@ -40,6 +40,7 @@ use uv_types::{
4040
HashStrategy, InFlight,
4141
};
4242
use uv_variant_frontend::VariantBuild;
43+
use uv_variants::variants_json::Provider;
4344
use uv_workspace::WorkspaceCache;
4445

4546
#[derive(Debug, Error)]
@@ -163,29 +164,12 @@ impl<'a> BuildDispatch<'a> {
163164
.collect();
164165
self
165166
}
166-
167-
pub async fn setup_variants(
168-
&self,
169-
backend: VariantProviderBackend,
170-
build_output: BuildOutput,
171-
) -> Result<VariantBuild, uv_variant_frontend::Error> {
172-
let builder = VariantBuild::setup(
173-
backend,
174-
self.interpreter,
175-
self,
176-
self.build_extra_env_vars.clone(),
177-
build_output,
178-
self.concurrency.builds,
179-
)
180-
.boxed_local()
181-
.await?;
182-
Ok(builder)
183-
}
184167
}
185168

186169
#[allow(refining_impl_trait)]
187170
impl BuildContext for BuildDispatch<'_> {
188171
type SourceDistBuilder = SourceBuild;
172+
type VariantsBuilder = VariantBuild;
189173

190174
fn interpreter(&self) -> &Interpreter {
191175
self.interpreter
@@ -525,6 +509,26 @@ impl BuildContext for BuildDispatch<'_> {
525509

526510
Ok(Some(filename))
527511
}
512+
513+
async fn setup_variants<'data>(
514+
&'data self,
515+
backend_name: String,
516+
backend: &'data Provider,
517+
build_output: BuildOutput,
518+
) -> anyhow::Result<VariantBuild> {
519+
let builder = VariantBuild::setup(
520+
backend_name,
521+
backend,
522+
self.interpreter,
523+
self,
524+
self.build_extra_env_vars.clone(),
525+
build_output,
526+
self.concurrency.builds,
527+
)
528+
.boxed_local()
529+
.await?;
530+
Ok(builder)
531+
}
528532
}
529533

530534
/// Shared state used during resolution and installation.

crates/uv-distribution-filename/Cargo.toml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ uv-normalize = { workspace = true }
2121
uv-pep440 = { workspace = true }
2222
uv-platform-tags = { workspace = true }
2323
uv-small-str = { workspace = true }
24-
uv-variants = { workspace = true }
2524

2625
memchr = { workspace = true }
2726
rkyv = { workspace = true, features = ["smallvec-1"] }

crates/uv-distribution-filename/src/wheel.rs

Lines changed: 59 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
use std::borrow::Cow;
21
use std::fmt::{Display, Formatter};
32
use std::hash::Hash;
43
use std::str::FromStr;
@@ -17,7 +16,6 @@ use uv_platform_tags::{
1716
AbiTag, LanguageTag, ParseAbiTagError, ParseLanguageTagError, ParsePlatformTagError,
1817
PlatformTag, TagCompatibility, Tags,
1918
};
20-
use uv_variants::VariantTag;
2119

2220
#[derive(
2321
Debug,
@@ -36,7 +34,7 @@ pub struct WheelFilename {
3634
pub name: PackageName,
3735
pub version: Version,
3836
tags: WheelTag,
39-
variant: Option<VariantTag>,
37+
variant: Option<String>,
4038
}
4139

4240
impl FromStr for WheelFilename {
@@ -166,8 +164,8 @@ impl WheelFilename {
166164
}
167165

168166
/// Return the wheel's variant tag, if present.
169-
pub fn variant(&self) -> Option<&VariantTag> {
170-
self.variant.as_ref()
167+
pub fn variant(&self) -> Option<&str> {
168+
self.variant.as_deref()
171169
}
172170

173171
/// Return the wheel's Python tags.
@@ -218,38 +216,6 @@ impl WheelFilename {
218216
///
219217
/// The originating `filename` is used for high-fidelity error messages.
220218
fn parse(stem: &str, filename: &str) -> Result<Self, WheelFilenameError> {
221-
// Extract variant from filenames with the format, e.g., `dummy_project-0.0.1-~36266d4d~-py3-none-any.whl`.
222-
// TODO(charlie): Integrate this into the filename parsing; it's just easier to do it upfront
223-
// for now.
224-
let mut variant: Option<VariantTag> = None;
225-
let stem = if let Some(tilde_start) = stem.find("-~") {
226-
if let Some(tilde_end) = stem[tilde_start + 1..].find("~-") {
227-
// Skip the "-~".
228-
let variant_start = tilde_start + 2;
229-
// End before the "~-".
230-
let variant_end = tilde_start + 1 + tilde_end;
231-
// Validate that the variant is exactly 8 bytes.
232-
let variant_str = &stem[variant_start..variant_end];
233-
if variant_str.len() == 8 && variant_str.as_bytes().iter().all(|&b| b.is_ascii()) {
234-
variant = Some(VariantTag::new(variant_str.to_string()));
235-
} else {
236-
return Err(WheelFilenameError::InvalidWheelFileName(
237-
filename.to_string(),
238-
format!("Variant must be exactly 8 ASCII characters, got: '{variant_str}'"),
239-
));
240-
}
241-
242-
// Create a new stem without the variant.
243-
let before_variant = &stem[..tilde_start];
244-
let after_variant = &stem[variant_end + 1..];
245-
Cow::Owned(format!("{before_variant}{after_variant}"))
246-
} else {
247-
Cow::Borrowed(stem)
248-
}
249-
} else {
250-
Cow::Borrowed(stem)
251-
};
252-
253219
// The wheel filename should contain either five or six entries. If six, then the third
254220
// entry is the build tag. If five, then the third entry is the Python tag.
255221
// https://www.python.org/dev/peps/pep-0427/#file-name-convention
@@ -283,24 +249,62 @@ impl WheelFilename {
283249
));
284250
};
285251

286-
let (name, version, build_tag, python_tag, abi_tag, platform_tag, is_small) =
252+
let (name, version, build_tag, python_tag, abi_tag, platform_tag, variant, is_small) =
287253
if let Some(platform_tag) = splitter.next() {
288-
if splitter.next().is_some() {
289-
return Err(WheelFilenameError::InvalidWheelFileName(
290-
filename.to_string(),
291-
"Must have 5 or 6 components, but has more".to_string(),
292-
));
254+
// Extract variant from filenames with the format, e.g., `ml_project-0.0.1-py3-none-any-cu128.whl`.
255+
// TODO(charlie): Integrate this into the filename parsing; it's just easier to do it upfront
256+
// for now.
257+
// 7 components: We have both a build tag and a variant_tag
258+
if let Some(variant_tag) = splitter.next() {
259+
if splitter.next().is_some() {
260+
return Err(WheelFilenameError::InvalidWheelFileName(
261+
filename.to_string(),
262+
"Must have 5 to 7 components, but has more".to_string(),
263+
));
264+
}
265+
(
266+
&stem[..version],
267+
&stem[version + 1..build_tag_or_python_tag],
268+
Some(&stem[build_tag_or_python_tag + 1..python_tag_or_abi_tag]),
269+
&stem[python_tag_or_abi_tag + 1..abi_tag_or_platform_tag],
270+
&stem[abi_tag_or_platform_tag + 1..platform_tag],
271+
&stem[platform_tag + 1..variant_tag],
272+
Some(&stem[variant_tag + 1..]),
273+
// Always take the slow path if build or variant tag are present.
274+
false,
275+
)
276+
} else {
277+
// 6 components: Check whether we have a build tag or variant tag
278+
if LanguageTag::from_str(
279+
&stem[build_tag_or_python_tag + 1..python_tag_or_abi_tag],
280+
)
281+
.is_ok()
282+
{
283+
(
284+
&stem[..version],
285+
&stem[version + 1..build_tag_or_python_tag],
286+
Some(&stem[build_tag_or_python_tag + 1..python_tag_or_abi_tag]),
287+
&stem[python_tag_or_abi_tag + 1..abi_tag_or_platform_tag],
288+
&stem[abi_tag_or_platform_tag + 1..platform_tag],
289+
&stem[platform_tag + 1..],
290+
None,
291+
// Always take the slow path if a build tag is present.
292+
false,
293+
)
294+
} else {
295+
(
296+
&stem[..version],
297+
&stem[version + 1..build_tag_or_python_tag],
298+
None,
299+
&stem[build_tag_or_python_tag + 1..python_tag_or_abi_tag],
300+
&stem[python_tag_or_abi_tag + 1..abi_tag_or_platform_tag],
301+
&stem[abi_tag_or_platform_tag + 1..platform_tag],
302+
Some(&stem[platform_tag + 1..]),
303+
// Always take the slow path if a build tag is present.
304+
false,
305+
)
306+
}
293307
}
294-
(
295-
&stem[..version],
296-
&stem[version + 1..build_tag_or_python_tag],
297-
Some(&stem[build_tag_or_python_tag + 1..python_tag_or_abi_tag]),
298-
&stem[python_tag_or_abi_tag + 1..abi_tag_or_platform_tag],
299-
&stem[abi_tag_or_platform_tag + 1..platform_tag],
300-
&stem[platform_tag + 1..],
301-
// Always take the slow path if a build tag is present.
302-
false,
303-
)
304308
} else {
305309
(
306310
&stem[..version],
@@ -309,6 +313,7 @@ impl WheelFilename {
309313
&stem[build_tag_or_python_tag + 1..python_tag_or_abi_tag],
310314
&stem[python_tag_or_abi_tag + 1..abi_tag_or_platform_tag],
311315
&stem[abi_tag_or_platform_tag + 1..],
316+
None,
312317
// Determine whether any of the tag types contain a period, which would indicate
313318
// that at least one of the tag types includes multiple tags (which in turn
314319
// necessitates taking the slow path).
@@ -365,7 +370,7 @@ impl WheelFilename {
365370
name,
366371
version,
367372
tags,
368-
variant,
373+
variant: variant.map(ToString::to_string),
369374
})
370375
}
371376
}

crates/uv-distribution-types/src/prioritized_distribution.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -532,6 +532,10 @@ impl PrioritizedDist {
532532
})
533533
}
534534

535+
pub fn wheels(&self) -> impl Iterator<Item = &(RegistryBuiltWheel, WheelCompatibility)> {
536+
self.0.wheels.iter()
537+
}
538+
535539
/// Return the hashes for each distribution.
536540
pub fn hashes(&self) -> &[HashDigest] {
537541
&self.0.hashes

crates/uv-distribution/Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ uv-platform-tags = { workspace = true }
3535
uv-pypi-types = { workspace = true }
3636
uv-redacted = { workspace = true }
3737
uv-types = { workspace = true }
38+
uv-variants = { workspace = true }
3839
uv-workspace = { workspace = true }
3940

4041
anyhow = { workspace = true }
@@ -48,6 +49,7 @@ reqwest-middleware = { workspace = true }
4849
rmp-serde = { workspace = true }
4950
rustc-hash = { workspace = true }
5051
serde = { workspace = true, features = ["derive"] }
52+
serde_json = { workspace = true }
5153
tempfile = { workspace = true }
5254
thiserror = { workspace = true }
5355
tokio = { workspace = true }

0 commit comments

Comments
 (0)