Support Pyodide interpreter in windows (#17658)

## Summary

This adds Pyodide interpreter support in windows environment. In Pyodide
0.29.2, we made some enhancements to run Pyodide CLI in windows. This PR
relaxes a check that was disabling `uv pip` in Windows + Pyodide and
adds integration test.

## Test Plan

Added integration test, also tested locally by running

```
uv python install cpython-3.13.2-emscripten-wasm32-musl
uv venv venv-pyodide -p cpython-3.13.2-emscripten-wasm32-musl
call venv-pyodide\Scripts\activate
uv pip install packaging
python -c "import packaging"
```
This commit is contained in:
Gyeongjae Choi
2026-01-27 09:39:45 +09:00
committed by GitHub
parent b5797b2ab4
commit d31d7d7d86
5 changed files with 48 additions and 5 deletions
+37
View File
@@ -615,6 +615,43 @@ jobs:
./uv pip install packaging
python -c 'import packaging'
integration-test-pyodide-windows:
name: "pyodide on windows"
timeout-minutes: 10
runs-on: windows-latest
# Github Actions Windows runner uses D drive as pwd.
# Pyodide CLI has an issue running cross-drive,
# So ensure that cache and Pyodide paths are on D drive as well.
env:
UV_CACHE_DIR: D:\uv-cache
PYODIDE_XBUILDENV_PATH: D:\pyodide-xbuildenv
steps:
- name: "Download binary"
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
with:
name: uv-windows-x86_64-${{ inputs.sha }}
- name: "Create a native virtual environment"
run: |
.\uv.exe venv venv-native -p 3.13
.\uv.exe pip install -p venv-native\Scripts\python.exe pyodide-build==0.31.1 pip
- name: "Install Pyodide interpreter"
run: |
& .\venv-native\Scripts\Activate.ps1
pyodide xbuildenv install 0.29.2
$env:PYODIDE_PYTHON = pyodide config get interpreter
$env:PYODIDE_INDEX = pyodide config get package_index
echo "PYODIDE_PYTHON=$env:PYODIDE_PYTHON" >> $env:GITHUB_ENV
echo "PYODIDE_INDEX=$env:PYODIDE_INDEX" >> $env:GITHUB_ENV
- name: "Create Pyodide virtual environment"
run: |
.\uv.exe venv -p $env:PYODIDE_PYTHON venv-pyodide
& .\venv-pyodide\Scripts\Activate.ps1
.\uv.exe pip install --extra-index-url=$env:PYODIDE_INDEX --no-build numpy
python -c 'import numpy'
integration-test-github-actions:
name: "github actions"
timeout-minutes: 10
Generated
+1
View File
@@ -7182,6 +7182,7 @@ dependencies = [
"tracing",
"uv-console",
"uv-fs",
"uv-platform-tags",
"uv-preview",
"uv-pypi-types",
"uv-python",
+2 -5
View File
@@ -30,12 +30,9 @@ impl Os {
/// Whether this OS can run the other OS.
pub fn supports(&self, other: Self) -> bool {
// Emscripten cannot run on Windows, but all other OSes can run Emscripten.
// Emscripten can run on any OS
if other.is_emscripten() {
return !self.is_windows();
}
if self.is_windows() && other.is_emscripten() {
return false;
return true;
}
// Otherwise, we require an exact match
+1
View File
@@ -20,6 +20,7 @@ workspace = true
[dependencies]
uv-console = { workspace = true }
uv-fs = { workspace = true }
uv-platform-tags = { workspace = true }
uv-preview = { workspace = true }
uv-pypi-types = { workspace = true }
uv-python = { workspace = true }
+7
View File
@@ -12,6 +12,7 @@ use owo_colors::OwoColorize;
use tracing::{debug, trace};
use uv_fs::{CWD, Simplified, cachedir};
use uv_platform_tags::Os;
use uv_preview::Preview;
use uv_pypi_types::Scheme;
use uv_python::managed::{PythonMinorVersionLink, create_link_to_executable};
@@ -314,6 +315,12 @@ pub(crate) fn create(
create_link_to_executable(targetwt.as_path(), &executable_target)
.map_err(Error::Python)?;
}
} else if matches!(interpreter.platform().os(), Os::Pyodide { .. }) {
// For Pyodide, link only `python.exe`.
// This should not be copied as `python.exe` is a wrapper that launches Pyodide.
let target = scripts.join(WindowsExecutable::Python.exe(interpreter));
create_link_to_executable(target.as_path(), &executable_target)
.map_err(Error::Python)?;
} else {
// Always copy `python.exe`.
copy_launcher_windows(