Following system colour scheme - Python 增强提案 Selected dark colour scheme - Python 增强提案 Selected light colour scheme - Python 增强提案

Python 增强提案

PEP 783 – Emscripten 打包

作者:
Hood Chatham <roberthoodchatham at gmail.com>
发起人:
Łukasz Langa <lukasz at python.org>
讨论至:
Discourse 帖子
状态:
草案
类型:
标准跟踪
主题:
打包
创建日期:
2025年3月28日
发布历史:
2025年4月2日, 2025年3月18日

目录

摘要

本 PEP 提出了一个新的平台标签系列 pyodide,用于 Pyodide Python 运行时的二进制 Python 包分发。

Emscripten 是一个完整的开源编译器工具链。它将 C/C++ 代码编译成 WebAssembly/JavaScript 可执行文件,用于 JavaScript 运行时,包括浏览器和 Node.js。Rust 语言也维护一个 Emscripten 目标。PEP 776 规定了 Python 对 Emscripten 的支持。

动机

Pyodide 是一个用于浏览器的 CPython 发行版。网络浏览器是一个通用的计算平台,可在 Windows、macOS、Linux 和所有智能手机上使用。数十万学生通过 Pyodide 学习了 Python,这些项目包括 CapytalePyodideU。Pyodide 也越来越多地被 Python 包用来提供交互式文档。

截至撰写本文时,Pyodide 目前维护着 255 个不同包的端口,包括 NumPy、SciPy、pandas、Polars、scikit-learn、OpenCV、PyArrow 和 Pillow 等主要科学 Python 包,以及 aiohttp、Requests、Pydantic、cryptography 和 orjson 等通用包。

大约有 60 个包也在其 CI 中针对 Pyodide 进行测试,包括 NumPy、pandas、awkward-cpp、scikit-image、statsmodels、PyArrow、Hypothesis 和 PyO3。

Python 包项目无法在 PyPI 上部署用于 Pyodide 的二进制发行版。相反,它们必须使用其他选项,例如 anaconda.orgjsdelivr.com。这给包维护者和用户都带来了不便。

基本原理

Emscripten 使用 musl libc 的变体。Emscripten 编译器不保证版本之间的 ABI 稳定性。许多 Emscripten 更新在偶然情况下是 ABI 兼容的,并且 Rust Emscripten 目标的行为就像 ABI 是稳定的,只是 偶尔会产生负面影响

有几个链接器标志可以调整 Emscripten ABI,因此为 Emscripten 编译运行的 Python 包必须确保匹配用于编译解释器的 ABI 敏感链接器标志,以避免加载时或运行时错误。Emscripten 编译器不断修复错误并添加对新 Web 平台功能的支持。因此,能够更新 ABI 具有显著的好处。

为了平衡包维护者的 ABI 稳定性需求和允许平台向前发展的 ABI 灵活性,Pyodide 计划为每个 Python 功能发布采用新的 ABI。

Pyodide 团队还协调 Pyodide 使用的 ABI 标志与 Rust 支持的 Emscripten ABI,以确保我们支持许多流行的 Rust 包。历史上,这项工作的大部分都与解栈 ABI 相关。例如,请参阅 此 Rust 主要变更提案

pyodide 平台标签仅适用于使用与 Pyodide 相同版本的 Emscripten 编译和链接,并带有相同 ABI 敏感标志的 Python 解释器。

规范

平台标签将采用以下形式

pyodide_${YEAR}_${PATCH}_wasm32

每个标签都将与指定的 Python 版本一起使用。例如,平台标签 pyodide_2025_0 将与 Python 3.13 一起使用。

Emscripten Wheel ABI

pyodide_<abi> 平台的规范包括

  • 使用的 Emscripten 编译器版本
  • 与解释器静态链接的库
  • 要使用的栈解绕 ABI
  • 加载器如何处理依赖项查找
  • 库不能使用 -pthread
  • 库应该与 -sWASM_BIGINT 链接

ABI 通过选择适当的 Emscripten 编译器版本并传递适当的编译器和链接器标志来选择。其他人可以构建自己的与 Pyodide ABI 兼容的 Python 解释器,无需使用 Pyodide 发行版本身。

Pyodide ABI 在 Pyodide 平台 ABI 文档中完整指定。

pyodide build 工具知道如何创建与 Pyodide ABI 匹配的 wheel。与 manylinux wheel 不同,构建 pyodide_<abi> wheel 不需要 Docker 容器。所需的只是一个 Linux 机器和适当版本的 Python、Node.js 和 Emscripten。

可以通过在 Pyodide 运行时中安装和导入 wheel 来验证它。因为 Pyodide 可以在具有强大沙盒保证的环境中运行,所以这样做不会产生安全风险。

确定 ABI 版本

Pyodide ABI 版本存储在 PYODIDE_ABI_VERSION 配置变量中,可以通过以下方式确定

pyodide_abi_version = sysconfig.get_config_var("PYODIDE_ABI_VERSION")

要生成兼容标签列表,可以使用以下代码

from packaging.tags import cpython_tags, _generic_platforms

def _emscripten_platforms() -> Iterator[str]:
    pyodide_abi_version = sysconfig.get_config_var("PYODIDE_ABI_VERSION")
    if pyodide_abi_version:
        yield f"pyodide_{pyodide_abi_version}_wasm32"
    yield from _generic_platforms()

emscripten_tags = cpython_tags(platforms=_emscripten_platforms())

此代码将添加到 pypa/packaging

包安装程序

安装程序应该使用上面显示的 _emscripten_platforms() 函数来确定哪些平台与 CPython 的 Emscripten 构建兼容。特别是,Pyodide ABI 版本通过 sysconfig.get_config_var("PYODIDE_ABI_VERSION") 暴露。

包索引

包索引 SHOULD 接受其平台标签与正则表达式 pyodide_[0-9]+_[0-9]+_wasm32 匹配的任何 wheel。

依赖项指定器标记

根据 PEP 776,在 Emscripten Python 中 sys.platform 返回 "emscripten"。要在依赖项指定器中检查 Emscripten 平台,可以使用 sys_platform == "emscripten"(或其否定)。

分类器

构建和测试 Emscripten wheel 的包可以通过添加 Environment :: WebAssembly :: Emscripten 分类器来声明这一点。PyPI 已经接受上传 带有此分类器的包

向后兼容性

此 PEP 没有向后兼容性问题。

安全隐患

此 PEP 没有安全隐患。

如何教授此内容

对于 Pyodide 用户,我们推荐 Pyodide 关于安装包的文档

对于包维护者,我们推荐 Pyodide 关于构建和测试包的文档

参考实现

对于构建包,请参阅 pyodide buildcibuildwheel

对于安装程序决定 wheel 标签是否与 Pyodide 解释器兼容,请参阅 pypa/packaging#804


来源: https://github.com/python/peps/blob/main/peps/pep-0783.rst

最后修改: 2025-04-07 10:40:17 GMT