mirror of
https://github.com/astral-sh/uv.git
synced 2025-07-24 13:43:45 +00:00
Implement ordering for Python architectures to prefer native installations (#13709)
Resolves https://github.com/astral-sh/uv/pull/13474#discussion_r2112586405 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.
This commit is contained in:
parent
59070b5b3f
commit
dfc85336f8
2 changed files with 32 additions and 3 deletions
|
@ -483,8 +483,10 @@ impl Ord for PythonInstallationKey {
|
|||
.cmp(&other.implementation)
|
||||
.then_with(|| self.version().cmp(&other.version()))
|
||||
.then_with(|| self.os.to_string().cmp(&other.os.to_string()))
|
||||
.then_with(|| self.arch.to_string().cmp(&other.arch.to_string()))
|
||||
// Architectures are sorted in preferred order, with native architectures first
|
||||
.then_with(|| self.arch.cmp(&other.arch).reverse())
|
||||
.then_with(|| self.libc.to_string().cmp(&other.libc.to_string()))
|
||||
.then_with(|| self.variant.cmp(&other.variant).reverse()) // we want Default to come first
|
||||
// Python variants are sorted in preferred order, with `Default` first
|
||||
.then_with(|| self.variant.cmp(&other.variant).reverse())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,7 +18,7 @@ pub enum Error {
|
|||
}
|
||||
|
||||
/// Architecture variants, e.g., with support for different instruction sets
|
||||
#[derive(Debug, Eq, PartialEq, Clone, Copy, Hash)]
|
||||
#[derive(Debug, Eq, PartialEq, Clone, Copy, Hash, Ord, PartialOrd)]
|
||||
pub enum ArchVariant {
|
||||
/// Targets 64-bit Intel/AMD CPUs newer than Nehalem (2008).
|
||||
/// Includes SSE3, SSE4 and other post-2003 CPU instructions.
|
||||
|
@ -37,6 +37,33 @@ pub struct Arch {
|
|||
pub(crate) variant: Option<ArchVariant>,
|
||||
}
|
||||
|
||||
impl Ord for Arch {
|
||||
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
|
||||
if self.family == other.family {
|
||||
return self.variant.cmp(&other.variant);
|
||||
}
|
||||
|
||||
let native = Arch::from_env();
|
||||
|
||||
// Prefer native architectures
|
||||
match (self.family == native.family, other.family == native.family) {
|
||||
(true, true) => unreachable!(),
|
||||
(true, false) => std::cmp::Ordering::Less,
|
||||
(false, true) => std::cmp::Ordering::Greater,
|
||||
(false, false) => {
|
||||
// Both non-native, fallback to lexicographic order
|
||||
self.family.to_string().cmp(&other.family.to_string())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialOrd for Arch {
|
||||
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
|
||||
Some(self.cmp(other))
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Eq, PartialEq, Clone, Copy, Hash)]
|
||||
pub struct Os(pub(crate) target_lexicon::OperatingSystem);
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue