Allow use of older variants on newer systems

This commit is contained in:
Zanie Blue 2025-04-21 17:34:25 -05:00
parent db98257f1a
commit 31ba0a23e3
6 changed files with 14932 additions and 14893 deletions

File diff suppressed because it is too large Load diff

View file

@ -90,10 +90,12 @@ class Arch:
return (self.family + "_" + self.variant) if self.variant else self.family
def __gt__(self, other) -> bool:
return (self.family, self.variant or "") > (other.family, other.variant or "")
# Note this is inverted to prefer newer variants
return (self.family, self.variant or "") < (other.family, other.variant or "")
def __lt__(self, other) -> bool:
return (self.family, self.variant or "") < (other.family, other.variant or "")
# Note this is inverted to prefer newer variants
return (self.family, self.variant or "") > (other.family, other.variant or "")
type PlatformTripleKey = tuple[str, str, str]

View file

@ -286,11 +286,13 @@ impl PythonDownloadRequest {
return false;
}
}
if let Some(implementation) = &self.implementation {
if key.implementation != LenientImplementationName::from(*implementation) {
return false;
}
}
// If we don't allow pre-releases, don't match a key with a pre-release tag
if !self.allows_prereleases() && key.prerelease.is_some() {
return false;

View file

@ -117,7 +117,12 @@ impl Arch {
return true;
}
// TODO: Implement `variant` support checks
if self
.variant
.is_some_and(|variant| variant.supports(other.variant))
{
return true;
}
// Windows ARM64 runs emulated x86_64 binaries transparently
if cfg!(windows) && matches!(self.family, target_lexicon::Architecture::Aarch64(_)) {
@ -134,10 +139,19 @@ impl Arch {
pub fn is_arm(&self) -> bool {
matches!(self.family, target_lexicon::Architecture::Arm(_))
}
#[must_use]
pub fn without_variant(self) -> Self {
Self {
family: self.family,
variant: None,
}
}
}
impl ArchVariant {
#[cfg(target_arch = "x86_64")]
/// Only Linux `x86_64` variants are published upstream at this time.
#[cfg(all(unix, target_arch = "x86_64"))]
pub fn from_env() -> Option<Self> {
if is_x86_feature_detected!("avx512f")
&& is_x86_feature_detected!("avx512bw")
@ -169,10 +183,31 @@ impl ArchVariant {
}
}
#[cfg(not(target_arch = "x86_64"))]
#[cfg(not(all(unix, target_arch = "x86_64")))]
pub fn from_env() -> Option<Self> {
None
}
/// Does the current variant support running the other?
///
/// When the variants are equal, this is always true. Otherwise, this is true if the given
/// variant is a subset of the current one.
pub(crate) fn supports(self, other: Option<Self>) -> bool {
// `None` can be used on any architecture
let Some(other) = other else {
return true;
};
// Equal variants are always supported
if self == other {
return true;
}
// Check for variant subsets
match self {
Self::V2 => false, // We already tested for equality and `None`
Self::V3 => matches!(other, Self::V2),
Self::V4 => matches!(other, Self::V2 | Self::V3),
}
}
}
impl Display for Libc {

View file

@ -94,7 +94,7 @@ fn python_find() {
// Request CPython 3.12 for the current platform
let os = Os::from_env();
let arch = Arch::from_env();
let arch = Arch::from_env().without_variant();
uv_snapshot!(context.filters(), context.python_find()
.arg(format!("cpython-3.12-{os}-{arch}"))

View file

@ -717,7 +717,7 @@ fn python_pin_resolve() {
// Request CPython 3.13 for the current platform
let os = Os::from_env();
let arch = Arch::from_env();
let arch = Arch::from_env().without_variant();
uv_snapshot!(context.filters(), context.python_pin().arg("--resolved")
.arg(format!("cpython-3.13-{os}-{arch}"))