Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 39 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -1294,6 +1294,45 @@ jobs:
run: |
.\uv.exe pip install anyio

integration-test-pyodide-linux:
timeout-minutes: 10
needs: build-binary-linux-libc
name: "integration test | pyodide on ubuntu"
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2

- name: "Download binary"
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
with:
name: uv-linux-libc-${{ github.sha }}

- name: "Prepare binary"
run: chmod +x ./uv

- name: "Create a native virtual environment"
run: |
./uv venv venv-native -p 3.12
# We use features added in 0.30.3 but there is no known breakage in
# newer versions.
./uv pip install -p venv-native/bin/python pyodide-build==0.30.3 pip

- name: "Install pyodide interpreter"
run: |
source ./venv-native/bin/activate
pyodide xbuildenv install 0.27.5
PYODIDE_PYTHON=$(pyodide config get interpreter)
PYODIDE_INDEX=$(pyodide config get package_index)
echo "PYODIDE_PYTHON=$PYODIDE_PYTHON" >> $GITHUB_ENV
echo "PYODIDE_INDEX=$PYODIDE_INDEX" >> $GITHUB_ENV

- name: "Create pyodide virtual environment"
run: |
./uv venv -p $PYODIDE_PYTHON venv-pyodide
source ./venv-pyodide/bin/activate
./uv pip install --extra-index-url=$PYODIDE_INDEX --no-build numpy
python -c 'import numpy'

integration-test-github-actions:
timeout-minutes: 10
needs: build-binary-linux-libc
Expand Down
23 changes: 23 additions & 0 deletions crates/uv-configuration/src/target_triple.rs
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,10 @@ pub enum TargetTriple {
#[serde(rename = "aarch64-manylinux_2_40")]
#[serde(alias = "aarch64-manylinux240")]
Aarch64Manylinux240,

/// A wasm32 target using the the Pyodide 2024 platform. Meant for use with Python 3.12.
#[cfg_attr(feature = "clap", value(name = "wasm32-pyodide2024"))]
Wasm32Pyodide2024,
}

impl TargetTriple {
Expand Down Expand Up @@ -450,6 +454,13 @@ impl TargetTriple {
},
Arch::Aarch64,
),
Self::Wasm32Pyodide2024 => Platform::new(
Os::Pyodide {
major: 2024,
minor: 0,
},
Arch::Wasm32,
),
}
}

Expand Down Expand Up @@ -490,6 +501,7 @@ impl TargetTriple {
Self::Aarch64Manylinux238 => "aarch64",
Self::Aarch64Manylinux239 => "aarch64",
Self::Aarch64Manylinux240 => "aarch64",
Self::Wasm32Pyodide2024 => "wasm32",
}
}

Expand Down Expand Up @@ -530,6 +542,7 @@ impl TargetTriple {
Self::Aarch64Manylinux238 => "Linux",
Self::Aarch64Manylinux239 => "Linux",
Self::Aarch64Manylinux240 => "Linux",
Self::Wasm32Pyodide2024 => "Emscripten",
}
}

Expand Down Expand Up @@ -570,6 +583,10 @@ impl TargetTriple {
Self::Aarch64Manylinux238 => "",
Self::Aarch64Manylinux239 => "",
Self::Aarch64Manylinux240 => "",
// This is the value Emscripten gives for its version:
// https://github.com/emscripten-core/emscripten/blob/4.0.8/system/lib/libc/emscripten_syscall_stubs.c#L63
// It doesn't really seem to mean anything? But for completeness we include it here.
Self::Wasm32Pyodide2024 => "#1",
}
}

Expand Down Expand Up @@ -610,6 +627,9 @@ impl TargetTriple {
Self::Aarch64Manylinux238 => "",
Self::Aarch64Manylinux239 => "",
Self::Aarch64Manylinux240 => "",
// This is the Emscripten compiler version for Pyodide 2024.
// See https://pyodide.org/en/stable/development/abi.html#pyodide-2024-0
Self::Wasm32Pyodide2024 => "3.1.58",
}
}

Expand Down Expand Up @@ -650,6 +670,7 @@ impl TargetTriple {
Self::Aarch64Manylinux238 => "posix",
Self::Aarch64Manylinux239 => "posix",
Self::Aarch64Manylinux240 => "posix",
Self::Wasm32Pyodide2024 => "posix",
}
}

Expand Down Expand Up @@ -690,6 +711,7 @@ impl TargetTriple {
Self::Aarch64Manylinux238 => "linux",
Self::Aarch64Manylinux239 => "linux",
Self::Aarch64Manylinux240 => "linux",
Self::Wasm32Pyodide2024 => "emscripten",
}
}

Expand Down Expand Up @@ -730,6 +752,7 @@ impl TargetTriple {
Self::Aarch64Manylinux238 => true,
Self::Aarch64Manylinux239 => true,
Self::Aarch64Manylinux240 => true,
Self::Wasm32Pyodide2024 => false,
}
}

Expand Down
7 changes: 6 additions & 1 deletion crates/uv-platform-tags/src/platform.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ pub enum Os {
Manylinux { major: u16, minor: u16 },
Musllinux { major: u16, minor: u16 },
Windows,
Pyodide { major: u16, minor: u16 },
Macos { major: u16, minor: u16 },
FreeBsd { release: String },
NetBsd { release: String },
Expand All @@ -67,6 +68,7 @@ impl fmt::Display for Os {
Self::Illumos { .. } => write!(f, "illumos"),
Self::Haiku { .. } => write!(f, "haiku"),
Self::Android { .. } => write!(f, "android"),
Self::Pyodide { .. } => write!(f, "pyodide"),
}
}
}
Expand Down Expand Up @@ -109,6 +111,7 @@ pub enum Arch {
S390X,
LoongArch64,
Riscv64,
Wasm32,
}

impl fmt::Display for Arch {
Expand All @@ -126,6 +129,7 @@ impl fmt::Display for Arch {
Self::S390X => write!(f, "s390x"),
Self::LoongArch64 => write!(f, "loongarch64"),
Self::Riscv64 => write!(f, "riscv64"),
Self::Wasm32 => write!(f, "wasm32"),
}
}
}
Expand Down Expand Up @@ -168,7 +172,7 @@ impl Arch {
// manylinux_2_36
Self::LoongArch64 => Some(36),
// unsupported
Self::Powerpc | Self::Armv5TEL | Self::Armv6L => None,
Self::Powerpc | Self::Armv5TEL | Self::Armv6L | Self::Wasm32 => None,
}
}

Expand All @@ -187,6 +191,7 @@ impl Arch {
Self::S390X => "s390x",
Self::LoongArch64 => "loongarch64",
Self::Riscv64 => "riscv64",
Self::Wasm32 => "wasm32",
}
}

Expand Down
54 changes: 54 additions & 0 deletions crates/uv-platform-tags/src/platform_tag.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,8 @@ pub enum PlatformTag {
Illumos { release_arch: SmallString },
/// Ex) `solaris_11_4_x86_64`
Solaris { release_arch: SmallString },
/// Ex) `pyodide_2024_0_wasm32`
Pyodide { major: u16, minor: u16 },
}

impl PlatformTag {
Expand All @@ -97,6 +99,7 @@ impl PlatformTag {
PlatformTag::Haiku { .. } => Some("Haiku"),
PlatformTag::Illumos { .. } => Some("Illumos"),
PlatformTag::Solaris { .. } => Some("Solaris"),
PlatformTag::Pyodide { .. } => Some("Pyodide"),
}
}
}
Expand Down Expand Up @@ -262,6 +265,7 @@ impl std::fmt::Display for PlatformTag {
Self::Haiku { release_arch } => write!(f, "haiku_{release_arch}"),
Self::Illumos { release_arch } => write!(f, "illumos_{release_arch}"),
Self::Solaris { release_arch } => write!(f, "solaris_{release_arch}_64bit"),
Self::Pyodide { major, minor } => write!(f, "pyodide_{major}_{minor}_wasm32"),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@hoodmane -- Should this not be emscripten_3_1_58_wasm32, for pyodide_2024_0?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I put up a PR here, I may be mistaken though: #14226

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah okay, I'm seeing that the wheels in pyodide config get package_index do use this pyodide tag. Should we support both?

}
}
}
Expand Down Expand Up @@ -616,6 +620,35 @@ impl FromStr for PlatformTag {
});
}

if let Some(rest) = s.strip_prefix("pyodide_") {
let mid =
rest.strip_suffix("_wasm32")
.ok_or_else(|| ParsePlatformTagError::InvalidArch {
platform: "pyodide",
tag: s.to_string(),
})?;
let underscore = memchr::memchr(b'_', mid.as_bytes()).ok_or_else(|| {
ParsePlatformTagError::InvalidFormat {
platform: "pyodide",
tag: s.to_string(),
}
})?;
let major: u16 = mid[..underscore].parse().map_err(|_| {
ParsePlatformTagError::InvalidMajorVersion {
platform: "pyodide",
tag: s.to_string(),
}
})?;

let minor: u16 = mid[underscore + 1..].parse().map_err(|_| {
ParsePlatformTagError::InvalidMinorVersion {
platform: "pyodide",
tag: s.to_string(),
}
})?;
return Ok(Self::Pyodide { major, minor });
}

Err(ParsePlatformTagError::UnknownFormat(s.to_string()))
}
}
Expand Down Expand Up @@ -900,6 +933,27 @@ mod tests {
);
}

#[test]
fn pyodide_platform() {
let tag = PlatformTag::Pyodide {
major: 2024,
minor: 0,
};
assert_eq!(
PlatformTag::from_str("pyodide_2024_0_wasm32").as_ref(),
Ok(&tag)
);
assert_eq!(tag.to_string(), "pyodide_2024_0_wasm32");

assert_eq!(
PlatformTag::from_str("pyodide_2024_0_wasm64"),
Err(ParsePlatformTagError::InvalidArch {
platform: "pyodide",
tag: "pyodide_2024_0_wasm64".to_string()
})
);
}

#[test]
fn unknown_platform() {
assert_eq!(
Expand Down
6 changes: 6 additions & 0 deletions crates/uv-platform-tags/src/tags.rs
Original file line number Diff line number Diff line change
Expand Up @@ -617,6 +617,12 @@ fn compatible_tags(platform: &Platform) -> Result<Vec<PlatformTag>, PlatformErro
arch,
}]
}
(Os::Pyodide { major, minor }, Arch::Wasm32) => {
vec![PlatformTag::Pyodide {
major: *major,
minor: *minor,
}]
}
_ => {
return Err(PlatformError::OsVersionDetectionError(format!(
"Unsupported operating system and architecture combination: {os} {arch}"
Expand Down
18 changes: 18 additions & 0 deletions crates/uv-python/python/get_interpreter_info.py
Original file line number Diff line number Diff line change
Expand Up @@ -510,6 +510,24 @@ def get_operating_system_and_architecture():
"major": int(version[0]),
"minor": int(version[1]),
}
elif operating_system == "emscripten":
pyodide_abi_version = sysconfig.get_config_var("PYODIDE_ABI_VERSION")
if not pyodide_abi_version:
print(
json.dumps(
{
"result": "error",
"kind": "emscripten_not_pyodide",
}
)
)
sys.exit(0)
version = pyodide_abi_version.split("_")
operating_system = {
"name": "pyodide",
"major": int(version[0]),
"minor": int(version[1]),
}
elif operating_system in [
"freebsd",
"netbsd",
Expand Down
2 changes: 2 additions & 0 deletions crates/uv-python/src/interpreter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -757,6 +757,8 @@ pub enum InterpreterInfoError {
python_major: usize,
python_minor: usize,
},
#[error("Only Pyodide is support for Emscripten Python")]
EmscriptenNotPyodide,
}

#[derive(Debug, Deserialize, Serialize, Clone)]
Expand Down
7 changes: 7 additions & 0 deletions crates/uv-python/src/platform.rs
Original file line number Diff line number Diff line change
Expand Up @@ -348,6 +348,10 @@ impl From<&uv_platform_tags::Arch> for Arch {
),
variant: None,
},
uv_platform_tags::Arch::Wasm32 => Self {
family: target_lexicon::Architecture::Wasm32,
variant: None,
},
}
}
}
Expand Down Expand Up @@ -380,6 +384,9 @@ impl From<&uv_platform_tags::Os> for Os {
uv_platform_tags::Os::NetBsd { .. } => Self(target_lexicon::OperatingSystem::Netbsd),
uv_platform_tags::Os::OpenBsd { .. } => Self(target_lexicon::OperatingSystem::Openbsd),
uv_platform_tags::Os::Windows => Self(target_lexicon::OperatingSystem::Windows),
uv_platform_tags::Os::Pyodide { .. } => {
Self(target_lexicon::OperatingSystem::Emscripten)
}
}
}
}
3 changes: 2 additions & 1 deletion crates/uv-torch/src/backend.rs
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,8 @@ impl TorchStrategy {
| Os::Dragonfly { .. }
| Os::Illumos { .. }
| Os::Haiku { .. }
| Os::Android { .. } => {
| Os::Android { .. }
| Os::Pyodide { .. } => {
Either::Right(std::iter::once(TorchBackend::Cpu.index_url()))
}
}
Expand Down
4 changes: 4 additions & 0 deletions docs/reference/cli.md
Original file line number Diff line number Diff line change
Expand Up @@ -1702,6 +1702,7 @@ interpreter. Use <code>--universal</code> to display the tree for all platforms,
<li><code>aarch64-manylinux_2_38</code>: An ARM64 target for the <code>manylinux_2_38</code> platform</li>
<li><code>aarch64-manylinux_2_39</code>: An ARM64 target for the <code>manylinux_2_39</code> platform</li>
<li><code>aarch64-manylinux_2_40</code>: An ARM64 target for the <code>manylinux_2_40</code> platform</li>
<li><code>wasm32-pyodide2024</code>: A wasm32 target using the the Pyodide 2024 platform. Meant for use with Python 3.12</li>
</ul></dd><dt id="uv-tree--python-version"><a href="#uv-tree--python-version"><code>--python-version</code></a> <i>python-version</i></dt><dd><p>The Python version to use when filtering the tree.</p>
<p>For example, pass <code>--python-version 3.10</code> to display the dependencies that would be included when installing on Python 3.10.</p>
<p>Defaults to the version of the discovered Python interpreter.</p>
Expand Down Expand Up @@ -3295,6 +3296,7 @@ by <code>--python-version</code>.</p>
<li><code>aarch64-manylinux_2_38</code>: An ARM64 target for the <code>manylinux_2_38</code> platform</li>
<li><code>aarch64-manylinux_2_39</code>: An ARM64 target for the <code>manylinux_2_39</code> platform</li>
<li><code>aarch64-manylinux_2_40</code>: An ARM64 target for the <code>manylinux_2_40</code> platform</li>
<li><code>wasm32-pyodide2024</code>: A wasm32 target using the the Pyodide 2024 platform. Meant for use with Python 3.12</li>
</ul></dd><dt id="uv-pip-compile--python-version"><a href="#uv-pip-compile--python-version"><code>--python-version</code></a> <i>python-version</i></dt><dd><p>The Python version to use for resolution.</p>
<p>For example, <code>3.8</code> or <code>3.8.17</code>.</p>
<p>Defaults to the version of the Python interpreter used for resolution.</p>
Expand Down Expand Up @@ -3533,6 +3535,7 @@ be used with caution, as it can modify the system Python installation.</p>
<li><code>aarch64-manylinux_2_38</code>: An ARM64 target for the <code>manylinux_2_38</code> platform</li>
<li><code>aarch64-manylinux_2_39</code>: An ARM64 target for the <code>manylinux_2_39</code> platform</li>
<li><code>aarch64-manylinux_2_40</code>: An ARM64 target for the <code>manylinux_2_40</code> platform</li>
<li><code>wasm32-pyodide2024</code>: A wasm32 target using the the Pyodide 2024 platform. Meant for use with Python 3.12</li>
</ul></dd><dt id="uv-pip-sync--python-version"><a href="#uv-pip-sync--python-version"><code>--python-version</code></a> <i>python-version</i></dt><dd><p>The minimum Python version that should be supported by the requirements (e.g., <code>3.7</code> or <code>3.7.9</code>).</p>
<p>If a patch version is omitted, the minimum patch version is assumed. For example, <code>3.7</code> is mapped to <code>3.7.0</code>.</p>
</dd><dt id="uv-pip-sync--quiet"><a href="#uv-pip-sync--quiet"><code>--quiet</code></a>, <code>-q</code></dt><dd><p>Use quiet output.</p>
Expand Down Expand Up @@ -3796,6 +3799,7 @@ should be used with caution, as it can modify the system Python installation.</p
<li><code>aarch64-manylinux_2_38</code>: An ARM64 target for the <code>manylinux_2_38</code> platform</li>
<li><code>aarch64-manylinux_2_39</code>: An ARM64 target for the <code>manylinux_2_39</code> platform</li>
<li><code>aarch64-manylinux_2_40</code>: An ARM64 target for the <code>manylinux_2_40</code> platform</li>
<li><code>wasm32-pyodide2024</code>: A wasm32 target using the the Pyodide 2024 platform. Meant for use with Python 3.12</li>
</ul></dd><dt id="uv-pip-install--python-version"><a href="#uv-pip-install--python-version"><code>--python-version</code></a> <i>python-version</i></dt><dd><p>The minimum Python version that should be supported by the requirements (e.g., <code>3.7</code> or <code>3.7.9</code>).</p>
<p>If a patch version is omitted, the minimum patch version is assumed. For example, <code>3.7</code> is mapped to <code>3.7.0</code>.</p>
</dd><dt id="uv-pip-install--quiet"><a href="#uv-pip-install--quiet"><code>--quiet</code></a>, <code>-q</code></dt><dd><p>Use quiet output.</p>
Expand Down
7 changes: 7 additions & 0 deletions uv.schema.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading