Skip to content

Commit dfc8533

Browse files
authored
Implement ordering for Python architectures to prefer native installations (#13709)
Resolves #13474 (comment) This kind of dynamic ordering freaks me out a little, but I think it's probably the best solution and is static at compile-time. Currently, we're just sorting by the stringified representation! which is just convenient for reproducibility, but we rely on these orderings for prioritization in discovery.
1 parent 59070b5 commit dfc8533

File tree

2 files changed

+32
-3
lines changed

2 files changed

+32
-3
lines changed

crates/uv-python/src/installation.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -483,8 +483,10 @@ impl Ord for PythonInstallationKey {
483483
.cmp(&other.implementation)
484484
.then_with(|| self.version().cmp(&other.version()))
485485
.then_with(|| self.os.to_string().cmp(&other.os.to_string()))
486-
.then_with(|| self.arch.to_string().cmp(&other.arch.to_string()))
486+
// Architectures are sorted in preferred order, with native architectures first
487+
.then_with(|| self.arch.cmp(&other.arch).reverse())
487488
.then_with(|| self.libc.to_string().cmp(&other.libc.to_string()))
488-
.then_with(|| self.variant.cmp(&other.variant).reverse()) // we want Default to come first
489+
// Python variants are sorted in preferred order, with `Default` first
490+
.then_with(|| self.variant.cmp(&other.variant).reverse())
489491
}
490492
}

crates/uv-python/src/platform.rs

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ pub enum Error {
1818
}
1919

2020
/// Architecture variants, e.g., with support for different instruction sets
21-
#[derive(Debug, Eq, PartialEq, Clone, Copy, Hash)]
21+
#[derive(Debug, Eq, PartialEq, Clone, Copy, Hash, Ord, PartialOrd)]
2222
pub enum ArchVariant {
2323
/// Targets 64-bit Intel/AMD CPUs newer than Nehalem (2008).
2424
/// Includes SSE3, SSE4 and other post-2003 CPU instructions.
@@ -37,6 +37,33 @@ pub struct Arch {
3737
pub(crate) variant: Option<ArchVariant>,
3838
}
3939

40+
impl Ord for Arch {
41+
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
42+
if self.family == other.family {
43+
return self.variant.cmp(&other.variant);
44+
}
45+
46+
let native = Arch::from_env();
47+
48+
// Prefer native architectures
49+
match (self.family == native.family, other.family == native.family) {
50+
(true, true) => unreachable!(),
51+
(true, false) => std::cmp::Ordering::Less,
52+
(false, true) => std::cmp::Ordering::Greater,
53+
(false, false) => {
54+
// Both non-native, fallback to lexicographic order
55+
self.family.to_string().cmp(&other.family.to_string())
56+
}
57+
}
58+
}
59+
}
60+
61+
impl PartialOrd for Arch {
62+
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
63+
Some(self.cmp(other))
64+
}
65+
}
66+
4067
#[derive(Debug, Eq, PartialEq, Clone, Copy, Hash)]
4168
pub struct Os(pub(crate) target_lexicon::OperatingSystem);
4269

0 commit comments

Comments
 (0)