ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

pydantic-core 浏览器测试环境指南:通过 Pyodide 在浏览器中运行 Rust 核心单元测试

pydantic-core 浏览器测试环境指南:通过 Pyodide 在浏览器中运行 Rust 核心单元测试 pydantic-core 浏览器测试环境指南通过 Pyodide 在浏览器中运行 Rust 核心单元测试【免费下载链接】pydanticData validation using Python type hints项目地址: https://gitcode.com/GitHub_Trending/py/pydanticpydantic-core 是 Pydantic 的 Rust 核心库负责数据校验与序列化的高性能实现。本指南聚焦仓库中的 wasm-preview 模块——它把 pydantic-core 编译为 WebAssembly并借助 Pyodide 在浏览器里直接运行完整的 pytest 单元测试套件。读完本文你将掌握在线运行 pydantic-core 测试的入口与版本控制方式、浏览器端执行的整体架构index.html → worker.js → run_tests.py 的调用链、底层 wasm wheel 的构建方法Makefile 的 build-wasm 目标以及各环节的已知限制与排错手段。一、项目背景为什么要在浏览器里跑 Rust 核心测试pydantic-core 采用 Rust 编写并通过 PyO3 绑定提供 Python 接口见 pydantic-core/pyproject.toml 中module-name pydantic_core._pydantic_core、bindings pyo3的配置其单元测试通常在本地或 CI 的原生 CPython 环境中执行。wasm-preview 提供了一个额外的验证渠道零依赖运行测试测试者无需安装 Rust 工具链、无需本地编译打开浏览器即可运行与 Release 版本对应的完整测试套件面向 wasm 目标的回归验证pydantic-core 本身就在 Rust 源码中针对 wasm 平台做了分支处理例如 recursion_guard.rs 中专门为 wasm栈空间极小下调了递归守卫上限测试代码中也大量使用sys.platform emscripten做条件跳过详见后文因此持续在浏览器环境跑测试本身就是对 wasm 平台适配的一种守护。从目录结构看该模块由三个核心文件组成文件职责index.html浏览器入口页面负责启动 Web Worker、接收并渲染 ANSI 终端输出worker.jsWorker 逻辑解析版本参数、下载 Release 源码压缩包、加载 Pyodide、驱动测试执行run_tests.py在 Pyodide 内部运行的 Python 脚本解压测试文件、micropip 安装依赖、调用 pytest.main()二、快速上手在浏览器中运行 pydantic-core 单元测试2.1 在线测试入口wasm-preview 的 README.md 提供了在线演示入口打开 index.html 即可开始测试。页面标题为 pydantic-core unit tests说明文字明确指出pydantic-core 被编译为 WebAssembly通过 Pyodide 在浏览器中运行。页面加载后终端输出区域pre idoutput会依次显示loading...、Starting worker...随后由 Worker 回传的运行日志会以 ANSI 彩色终端的形式实时渲染index.html中通过ansi-to-html库把原始输出转换为 HTML。2.2 通过 URL 查询参数指定测试版本默认情况下测试针对 pydantic-core 的最新 Release 运行。要针对特定版本测试在 URL 上追加查询参数即可?pydantic_core_versionv2.4.0例如完整 URL 形如.../index.html?pydantic_core_versionv2.4.0。该参数在 worker.js 中被解析若未提供则通过 GitHub Releases API 获取最新 Release 的 tag_name若提供则直接采用该 tag。随后 Worker 会下载对应 tag 的源码压缩包archive/refs/tags/{tag}.zip作为测试用例来源并据此拼接对应的 wasm wheel 下载地址。2.3 输出停滞时的排查建议README 明确指出如果输出看起来提前停止了请打开浏览器开发者控制台Developer Console查看更多细节。这是因为 Worker 内任何未捕获的异常都会在控制台留下堆栈见 worker.js 的console.error(err)页面终端区域只会显示Error: ...一行完整错误信息需要到控制台查看。三、架构拆解浏览器端测试执行的完整调用链3.1 index.html页面与终端渲染index.html 的页面结构很简单一个输出容器section内嵌pre idoutput。其核心逻辑是读取当前 URL 的查询参数new URLSearchParams(location.search)并追加tsDate.now()时间戳参数防止缓存以该查询参数实例化 Web Workernew Worker(./worker.js?...)监听 Worker 消息字符串消息直接追加到终端缓冲区二进制消息则按字节块用TextDecoder解码后追加通过ansi-to-html把累积的终端文本转为带颜色的 HTML 渲染进页面并自动滚动到底部。值得注意的一个细节页面把 Worker 消息分成「字符串」和「字节数组」两种类型处理这与 worker.js 中「先缓冲输出、每 100ms 批量 post 一次」的节流策略对应——大量字符输出时按块推送避免每条消息都触发一次页面重绘。3.2 worker.js版本解析、资源下载与 Pyodide 启动worker.js 是运行的核心驱动器主要步骤解析版本从 URL 查询参数读取pydantic_core_version缺省时请求 Releases API 获取最新版本号并行下载三类资源Promise.all./run_tests.py以文本方式获取同样带时间戳防缓存对应 tag 的仓库源码 zip以二进制方式获取并转为 base64 字符串供 Python 侧解压测试文件Pyodide 运行时https://cdn.jsdelivr.net/pyodide/v0.27.7/full/pyodide.js通过importScripts加载初始化 Pyodide调用loadPyodide()随后用 Emscripten 的FS与TTY模块自定义/dev/stdin、/dev/stdout、/dev/stderr设备setupStreams把 Python 侧的 print 输出重定向到 Worker 的消息通道实现浏览器终端的实时流式显示预加载 Python 包pyodide.loadPackage([micropip, pytest, numpy, pygments])执行测试pyodide.runPythonAsync(run_tests.py 源码, {globals: {pydantic_core_version, tests_zip}})把版本号和 base64 编码的测试压缩包注入 Python 全局命名空间。代码注释里还说明了一个关键约束源码 zip 下载使用的提交注释提到 e4cf2e2与所用 wasm wheel 的版本保持一致从而保证「测试代码版本」与「被测二进制版本」匹配、测试可以通过。3.3 run_tests.pyPyodide 内的解压、装依赖与 pytestrun_tests.py 运行于 Pyodide 环境内是测试执行的 Python 侧主体打印环境信息输出 Pyodide 版本号与测试压缩包大小Using pyodide version: ...、Extracting test files (size: ...)解压测试文件把 base64 解码后的 zip 内容解压并通过正则re.subn(r^pydantic-core-.?/tests/, tests/, name)把源码包内的测试目录重命名为tests/随后写入虚拟文件系统安装依赖通过micropip.install([...])安装全部运行测试所需的 Python 包列表包括dirty-equals断言辅助库hypothesis属性测试框架pydantic-core 的测试大量使用 hypothesis如 tests/test_hypothesis.pypytest-speed、pytest-mockpytest 插件tzdata时区数据pydantic-core 的 datetime 校验测试依赖inline-snapshot0.21、typing-extensions4.14.1、typing-inspection测试与类型相关依赖以及关键项——对应版本的 pydantic-core wasm wheel其下载地址拼接规则为pydantic_core-{tag}-cp312-cp312-emscripten_3_1_58_wasm32.whlcp312 表示 CPython 3.12 ABIemscripten_3_1_58_wasm32 是 Emscripten 工具链版本与 wasm 目标刷新导入缓存并运行测试importlib.invalidate_caches()后直接调用pytest.main()pytest 会自动收集tests/目录下的全部测试用例执行。脚本开头还有一行针对 M1 Mac 的实用注释与sys.setrecursionlimit(200)设置说明在部分本地环境下需要手动调低递归限制这也侧面反映了 wasm 环境栈空间受限的特点。四、底层支撑wasm wheel 是如何构建的浏览器端安装的emscripten_3_1_58_wasm32wheel 来自 pydantic-core 的 Release 产物其构建入口在 Makefile 的build-wasm目标.PHONY: build-wasm ## Build the WebAssembly version of the package build-wasm: echo This requires python 3.13, maturin and emsdk to be installed uvx maturin build --release --target wasm32-unknown-emscripten --out dist -i 3.13 ls -lh dist要点解读前置条件需要 Python 3.13、maturin 构建工具以及 Emscripten SDKemsdk注释明确了这三项依赖缺一不可构建命令maturin build --release --target wasm32-unknown-emscripten -i 3.13表示用 Python 3.13 的解释器元数据、面向wasm32-unknown-emscripten目标做 Release 构建产物输出到dist/目录版本对应关系README 中「pydantic-core 低于 v0.23.0 无法运行」的限制正源于此——v0.23.0 之前构建的是 CPython 3.10 的 wasm 二进制而当前 Pyodide 运行时基于 Python 3.11ABI 不兼容因而无法加载配套依赖组pyproject.toml 中定义了wasm [{ include-group dev }, ruff]的额外依赖组表明 wasm 场景的本地开发沿用 dev 组依赖。五、平台适配测试代码对 emscripten 的特殊处理wasm 环境的特殊性无子进程、栈空间小、部分特性缺失在测试套件中也有系统性体现这些正是浏览器端运行时会被触发或跳过的分支深度递归跳过tests/benchmarks/test_micro_benchmarks.py 定义skip_wasm_deep_stack pytest.mark.skipif(sys.platform emscripten, reasonwasm does not have enough stack space to recurse very deep)并标注在两处深度递归基准测试上子进程类测试跳过test_errors.py与tests/validators/test_decimal.py中均有pytest.mark.skipif(sys.platform emscripten, reasonno subprocesses on emscripten)——wasm 环境没有子进程能力序列化函数测试tests/serializers/test_functions.py 对emscripten以及 pypy、graalpy、win32平台跳过某类用例docstring 测试降级tests/test_docstrings.py 在 emscripten 平台不导入pytest_examples插件hypothesis 偶发失败tests/test_hypothesis.py 对 emscripten 标注了「有时会失败、原因未知」的跳过注释。这些sys.platform emscripten分支证明wasm-preview 并非简单地把测试搬进浏览器而是整个项目对 wasm 目标持续适配与回归的一部分。六、已知限制与排错清单综合 README.md 与源码整理出以下注意事项限制 / 现象说明与建议版本低于 v0.23.0 无法运行早期构建的是 CPython 3.10 的 wasm 二进制与当前 Pyodide 的 Python 3.11 运行时 ABI 不兼容请使用 v0.23.0 及以上的 pydantic_core_versionChrome 上测试提前冻结对 pydantic-core2.2.0 之前的版本测试在完成约 10%–15% 时会在 Chrome 中卡住原因是疑似 V8 引擎 bug社区 issue 为 pyodide/pyodide#3792。规避方式改用更高版本测试或换用其他浏览器输出提前停止优先打开浏览器开发者控制台查看完整错误堆栈页面终端只显示错误摘要wasm 平台能力受限无子进程、栈空间小等限制已由测试套件内的大量skipif(emscripten)分支处理属预期行为七、小结wasm-preview 展示了 pydantic-core 多平台验证的一种轻量方案借助 Pyodide 与 Emscripten把 Rust 核心的完整 pytest 套件搬到浏览器中运行。通过?pydantic_core_version参数可锁定任意受支持版本的测试配合 index.html、worker.js、run_tests.py 三件套开发者无需任何本地工具链即可复现 Release 版本的测试结果。若需自行构建对应 wheel可参考 Makefile 的build-wasm目标但需注意 Python 3.13、maturin 与 emsdk 三项前置环境以及 v0.23.0 版本下限和旧版本在 Chrome 上的冻结问题。【免费下载链接】pydanticData validation using Python type hints项目地址: https://gitcode.com/GitHub_Trending/py/pydantic创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表