Pyodide 现在可直接从 PyPI 安装 WASM 轮子
Simon Willison··作者 Simon Willison
关键信息
这项新支持面向 PEP 783 定义的 PyEmscripten 平台,也就是 Pyodide 用来识别 WASM 轮子的兼容层。文章提到,以前 Pyodide 维护者要自己维护、构建并托管 300 多个包,而且每增加一个新包都需要人工审核。
资讯摘要
Pyodide 314.0 发布中带来了一个长期以来备受期待的打包改进:为 Pyodide 构建的 Python 包,或者任何兼容 PEP 783 中 PyEmscripten 平台的运行时,现在都可以直接发布到 PyPI,并在运行时安装。文章指出,这意味着分发责任将从 Pyodide 维护者转回普通包维护者手中。此前,Pyodide 团队必须自己维护、构建并托管 300 多个包,这不仅带来了很大的维护负担,也因为每个新包都要人工审核而限制了社区增长。新的流程允许维护者像发布 Linux、macOS 或 Windows 的原生 wheel 一样,直接把 Pyodide wheel 发布到 PyPI。
文章还提到,实现这一能力的 PyPI Warehouse PR 已于 4 月 21 日合并。Simon Willison 表示,他长期以来都对这个限制感到沮丧,因为虽然 C 或 Rust 扩展可以编译成 WebAssembly,但过去没有简单的分发方式。为了庆祝这一变化,他把自己的一个实验项目打包成了新的 PyPI 项目 luau-wasm。这个包会发布一个较小的 PyEmscripten wheel,并且可以在 Pyodide 中通过 micropip 安装,然后在浏览器里导入并运行 Luau 代码。

资讯正文
Pyodide 314.0 版本发布公告(经由 Hacker News)里包含了一则我期待已久的消息:
你现在可以将为 Pyodide 构建的 Python 包(或任何与 <a href="https://pyodide.org/en/stable/development/abi.html">PEP 783 中定义的 PyEmscripten 平台</a> 兼容的 Python 运行时)直接发布到 PyPI,并在运行时安装它们。
此前,Pyodide 维护者不得不自行维护、构建并托管 300 多个包。这给维护者带来了很大的负担,也成了社区的一大瓶颈,因为每一个新包都需要人工审核。
从现在开始,包维护者只需像为 Linux、macOS 或 Windows 构建并发布原生 wheel 一样,直接构建并将 Pyodide wheels 发布到 PyPI 即可。
这是 <a href="https://github.com/pypi/warehouse/pull/19804">PyPI 本身为此提供支持的 PR</a>,它已于 4 月 21 日合入。
我很喜欢 <a href="https://pyodide.org">Pyodide</a>,过去也曾因这一限制而感到沮丧。把 C 或 Rust 扩展编译成 wheel 文件里的 WASM 是可行的,但在此之前,一直没有简便的方法来分发它们。
多亏了很多人的努力,这个问题现在已经解决了!
<h4 id="trying-it-out-with-luau-wasm">用 luau-wasm 试一试</h4>
我决定找些东西来打包,以示庆祝。我手头其实有不少实验性的 Pyodide 项目,但就这个场景而言,最合适的似乎是我 3 月 9 日做的 <a href="https://github.com/simonw/research/tree/main/pluau-wasm-pyodide#readme">Luau WebAssembly 研究实验</a>。
<a href="https://luau.org">Luau</a> 是一种“基于 Lua 的小型、快速、可嵌入编程语言,带有渐进类型系统”,由 <a href="https://luau.org/news/2022-11-04-luau-origins-and-evolution/">Roblox 开发</a>,并以 MIT 许可证发布。
它是用 C++ 编写的。我早就知道可以把它编译成 WebAssembly,并让它在 Pyodide 中运行,所以我让 <a href="https://gist.github.com/simonw/1761eab6ba11d4053f56f955a28ad76b">Codex + GPT-5.5 xhigh</a> 去负责把我的实验打包,并通过 GitHub Actions 将其发布到 PyPI。
这花了一些反复调试,但结果如下:<a href="https://pypi.org/project/luau-wasm/">luau-wasm</a> 是一个全新的 PyPI 包,它发布了一个 276KB 的 <code>luau_wasm-0.1a0-cp314-cp314-pyemscripten_2026_0_wasm32.whl</code> 文件,在 Pyodide 中可以这样使用:
<pre><span class="pl-k">import</span> <span class="pl-s1">micropip</span>
<span class="pl-k">await</span> <span class="pl-s1">micropip</span>.<span class="pl-c1">install</span>(<span class="pl-s">"luau-wasm"</span>)
<span class="pl-k">import</span> <span class="pl-s1">luau_wasm</span>
<span class="pl-en">print</span>(<span class="pl-s1">luau_wasm</span>.<span class="pl-c1">execute</span>(<span class="pl-s">r'''</span>
<span class="pl-s">local animals = {"fox", "owl", "frog", "rabbit"}</span>
table.sort(animals, function(a, b) return #a < #b end)
for i, name in animals do print(i .. ". " .. name .. " (" .. #name .. ")") end
你可以在 Pyodide REPL 演示中运行这段代码,看看它实际如何工作。
luau-wasm 的 GitHub 仓库包含了所有构建和部署脚本(使用的是最新的 cibuildwheel),并且还部署了一个 HTML 演示页面,它会加载 Pyodide,安装 luau-wasm,并提供一个用于试用的界面:https://simonw.github.io/luau-wasm/
截图:一个名为“Luau WASM”的网页应用,副标题为“在浏览器中通过 Pyodide 运行 Luau,方法是从 PyPI 安装 luau-wasm WebAssembly wheel。”右上角有一个绿色的“Ready”状态徽标。下面有示例按钮:“Hello World”、“Variables”、“Tables”、“Fibonacci”、“Runtime Error”。“LUAU SOURCE”代码编辑器中包含:local function fib(n: number): number / if n < 2 then return n end / return fib(n - 1) + fib(n - 2) / end / local out = {} / for i = 0, 12 do / table.insert(out, tostring(fib(i))) / end / print(table.concat(out, ", ")).右侧是一个“OUTPUT”面板,带有“Copy”按钮,显示深色终端输出:0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144。左下角有一个蓝色“Run”按钮、一个“Clear”按钮,以及文本“6.0 ms”。
有多少包已经在使用它了?
我很好奇,目前有多少包正在为这个平台发布 wheels。
经过一些与 ChatGPT 的琢磨之后,我得到了这段 BigQuery SQL,并将其运行在 PyPI 的 BigQuery 公共数据集上。这里是查询结果的原始 JSON,这里还有一个可在 Datasette Lite 中运行的 SQLite SQL 查询,它按最近上传日期对包进行去重。
如果查询正确,那么目前已经有 28 个 PyPI 包在使用新的 <code>pyemscripten_202*_wasm32</code> 标签发布:
<a href="https://pypi.org/project/luau-wasm/">luau-wasm</a>、<a href="https://pypi.org/project/uuid7-rs/">uuid7-rs</a>、<a href="https://pypi.org/project/cmm-16bit/">cmm-16bit</a>、<a href="https://pypi.org/project/pyOpenTTDAdmin/">pyOpenTTDAdmin</a>、<a href="https://pypi.org/project/imgui-bundle/">imgui-bundle</a>、<a href="https://pypi.org/project/numbertoolkit/">numbertoolkit</a>、<a href="https://pypi.org/project/bashkit/">bashkit</a>、<a href="https://pypi.org/project/geoarrow-rust-core/">geoarrow-rust-core</a>、<a href="https://pypi.org/project/arro3-io/">arro3-io</a>、<a href="https://pypi.org/project/arro3-core/">arro3-core</a>、<a href="https://pypi.org/project/arro3-compute/">arro3-compute</a>、<a href="https://pypi.org/project/onnx/">onnx</a>、<a href="https://pypi.org/project/powerfit-em/">powerfit-em</a>、<a href="https://pypi.org/project/tcod/">tcod</a>、<a href="https://pypi.org/project/chonkie-core/">chonkie-core</a>、<a href="https://pypi.org/project/tokie/">tokie</a>、<a href="https://pypi.org/project/robotraconteur/">robotraconteur</a>、<a href="https://pypi.org/project/pydantic_core/">pydantic_core</a>、<a href="https://pypi.org/project/yaml-rs/">yaml-rs</a>、<a href="https://pypi.org/project/cadquery-ocp-novtk-OCP.wasm/">cadquery-ocp-novtk-OCP.wasm</a>、<a href="https://pypi.org/project/uuid_utils/">uuid_utils</a>、<a href="https://pypi.org/project/base64_utils/">base64_utils</a>、<a href="https://pypi.org/project/pycdfpp/">pycdfpp</a>、<a href="https://pypi.org/project/lib3mf-OCP.wasm/">lib3mf-OCP.wasm</a>、<a href="https://pypi.org/project/typst/">typst</a>、<a href="https://pypi.org/project/toml-rs/">toml-rs</a>、<a href="https://pypi.org/project/onnx-weekly/">onnx-weekly</a>、<a href="https://pypi.org/project/dummy-pyodide-ext-test/">dummy-pyodide-ext-test</a></p>
希望在未来几个月和几年里,我们能看到更多这样的包出现。
来源与参考
收录于 2026-06-15