Allow use of x86-64 Python on ARM Windows (#11625)

Closes https://github.com/astral-sh/uv/issues/11493
This commit is contained in:
Zanie Blue 2025-02-19 12:01:46 -06:00 committed by GitHub
parent 80b0d4c4e2
commit fdebc0c7fd
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 33 additions and 7 deletions

View file

@ -250,18 +250,20 @@ impl PythonDownloadRequest {
.filter(move |download| self.satisfied_by_download(download))
}
/// Whether this request is satisfied by the key of an existing installation.
/// Whether this request is satisfied by an installation key.
pub fn satisfied_by_key(&self, key: &PythonInstallationKey) -> bool {
if let Some(arch) = &self.arch {
if key.arch != *arch {
return false;
}
}
if let Some(os) = &self.os {
if key.os != *os {
return false;
}
}
if let Some(arch) = &self.arch {
if !arch.supports(key.arch) {
return false;
}
}
if let Some(libc) = &self.libc {
if key.libc != *libc {
return false;

View file

@ -250,7 +250,10 @@ impl ManagedPythonInstallations {
.find_all()?
.filter(move |installation| {
installation.key.os == os
&& installation.key.arch.family == arch.family
&& (arch.supports(installation.key.arch)
// TODO(zanieb): Allow inequal variants, as `Arch::supports` does not
// implement this yet. See https://github.com/astral-sh/uv/pull/9788
|| arch.family == installation.key.arch.family)
&& installation.key.libc == libc
});
@ -665,6 +668,7 @@ impl ManagedPythonInstallation {
}
}
// TODO(zanieb): Only used in tests now.
/// Generate a platform portion of a key from the environment.
pub fn platform_key_from_env() -> Result<String, Error> {
let os = Os::from_env();

View file

@ -103,6 +103,26 @@ impl Arch {
}
}
/// Does the current architecture support running the other?
///
/// When the architecture is equal, this is always true. Otherwise, this is true if the
/// architecture is transparently emulated or is a microarchitecture with worse performance
/// characteristics.
pub(crate) fn supports(self, other: Self) -> bool {
if self == other {
return true;
}
// TODO: Implement `variant` support checks
// Windows ARM64 runs emulated x86_64 binaries transparently
if cfg!(windows) && matches!(self.family, target_lexicon::Architecture::Aarch64(_)) {
return other.family == target_lexicon::Architecture::X86_64;
}
false
}
pub fn family(&self) -> target_lexicon::Architecture {
self.family
}