Skip to content

Commit a1610c7

Browse files
zaniebGankra
andauthored
Add Windows x86-32 emulation support to interpreter architecture checks (#13475)
Closes #13471 Refactors the logic there a bit too. --------- Co-authored-by: Aria Desires <[email protected]>
1 parent c7aaa8b commit a1610c7

File tree

2 files changed

+94
-7
lines changed

2 files changed

+94
-7
lines changed

crates/uv-platform/src/lib.rs

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
use std::cmp;
44
use std::fmt;
55
use std::str::FromStr;
6+
use target_lexicon::Architecture;
67
use thiserror::Error;
78
use tracing::trace;
89

@@ -91,13 +92,28 @@ impl Platform {
9192
return true;
9293
}
9394

94-
// Windows ARM64 runs emulated x86_64 binaries transparently
95-
// Similarly, macOS aarch64 runs emulated x86_64 binaries transparently if you have Rosetta
96-
// installed. We don't try to be clever and check if that's the case here, we just assume
97-
// that if x86_64 distributions are available, they're usable.
98-
if (self.os.is_windows() || self.os.is_macos())
99-
&& matches!(self.arch.family(), target_lexicon::Architecture::Aarch64(_))
100-
&& matches!(other.arch.family(), target_lexicon::Architecture::X86_64)
95+
#[allow(clippy::unnested_or_patterns)]
96+
if self.os.is_windows()
97+
&& matches!(
98+
(self.arch.family(), other.arch.family()),
99+
// 32-bit x86 binaries work fine on 64-bit x86 windows
100+
(Architecture::X86_64, Architecture::X86_32(_)) |
101+
// Both 32-bit and 64-bit binaries are transparently emulated on aarch64 windows
102+
(Architecture::Aarch64(_), Architecture::X86_64) |
103+
(Architecture::Aarch64(_), Architecture::X86_32(_))
104+
)
105+
{
106+
return true;
107+
}
108+
109+
if self.os.is_macos()
110+
&& matches!(
111+
(self.arch.family(), other.arch.family()),
112+
// macOS aarch64 runs emulated x86_64 binaries transparently if you have Rosetta
113+
// installed. We don't try to be clever and check if that's the case here,
114+
// we just assume that if x86_64 distributions are available, they're usable.
115+
(Architecture::Aarch64(_), Architecture::X86_64)
116+
)
101117
{
102118
return true;
103119
}

crates/uv/tests/it/python_install.rs

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2765,6 +2765,77 @@ fn python_install_emulated_macos() {
27652765
");
27662766
}
27672767

2768+
#[cfg(all(target_os = "windows", target_arch = "x86_64"))]
2769+
#[test]
2770+
fn python_install_emulated_windows_x86_on_x64() {
2771+
let context: TestContext = TestContext::new_with_versions(&[])
2772+
.with_filtered_exe_suffix()
2773+
.with_managed_python_dirs()
2774+
.with_python_download_cache();
2775+
2776+
// Before installation, `uv python list` should not show the x86_32 download
2777+
uv_snapshot!(context.filters(), context.python_list().arg("3.13"), @r"
2778+
success: true
2779+
exit_code: 0
2780+
----- stdout -----
2781+
cpython-3.13.9-windows-x86_64-none <download available>
2782+
2783+
----- stderr -----
2784+
");
2785+
2786+
// Install an x86_32 version (assuming an x64 host)
2787+
uv_snapshot!(context.filters(), context.python_install().arg("3.13-x86"), @r"
2788+
success: true
2789+
exit_code: 0
2790+
----- stdout -----
2791+
2792+
----- stderr -----
2793+
Installed Python 3.13.9 in [TIME]
2794+
+ cpython-3.13.9-windows-x86-none (python3.13)
2795+
");
2796+
2797+
// It should be discoverable with `uv python find`
2798+
uv_snapshot!(context.filters(), context.python_find().arg("3.13"), @r"
2799+
success: true
2800+
exit_code: 0
2801+
----- stdout -----
2802+
[TEMP_DIR]/managed/cpython-3.13.9-windows-x86-none/python
2803+
2804+
----- stderr -----
2805+
");
2806+
2807+
// And included in `uv python list`
2808+
uv_snapshot!(context.filters(), context.python_list().arg("3.13"), @r"
2809+
success: true
2810+
exit_code: 0
2811+
----- stdout -----
2812+
cpython-3.13.9-windows-x86_64-none <download available>
2813+
cpython-3.13.9-windows-x86-none managed/cpython-3.13.9-windows-x86-none/python
2814+
2815+
----- stderr -----
2816+
");
2817+
2818+
uv_snapshot!(context.filters(), context.python_install().arg("3.13-x86_64"), @r"
2819+
success: true
2820+
exit_code: 0
2821+
----- stdout -----
2822+
2823+
----- stderr -----
2824+
Installed Python 3.13.9 in [TIME]
2825+
+ cpython-3.13.9-windows-x86_64-none
2826+
");
2827+
2828+
// Once we've installed the native version, it should be preferred over x86_32
2829+
uv_snapshot!(context.filters(), context.python_find().arg("3.13"), @r"
2830+
success: true
2831+
exit_code: 0
2832+
----- stdout -----
2833+
[TEMP_DIR]/managed/cpython-3.13.9-windows-x86_64-none/python
2834+
2835+
----- stderr -----
2836+
");
2837+
}
2838+
27682839
// A virtual environment should track the latest patch version installed.
27692840
#[test]
27702841
fn install_transparent_patch_upgrade_uv_venv() {

0 commit comments

Comments
 (0)