From 2f81d4f0658955934f591f90ae5ada9ca2ab13a8 Mon Sep 17 00:00:00 2001 From: Andrew Stein Date: Wed, 24 Jun 2026 01:00:21 -0400 Subject: [PATCH] Support PEP 783 (pypi emscripten wheels) Signed-off-by: Andrew Stein --- .github/workflows/build.yaml | 24 +++++++++++++++++++++--- package.json | 2 +- rust/perspective-python/build.mjs | 6 +++++- rust/perspective-python/pyproject.toml | 6 ++++-- rust/perspective-python/requirements.txt | 2 +- tools/scripts/workspace.mjs | 2 +- 6 files changed, 33 insertions(+), 9 deletions(-) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 09e85ce380..8a25739903 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -393,7 +393,7 @@ jobs: arch: - x86_64 python-version: - - 3.11 + - "3.13" node-version: [22.x] steps: - name: Checkout @@ -424,6 +424,24 @@ jobs: PACKAGE: "python" CI: 1 + - name: Verify wheel is PyPI-compatible (PEP 783) + shell: bash + run: | + python -m pip install --quiet --upgrade twine "packaging>=24.2" + shopt -s nullglob + wheels=(rust/target/wheels/*.whl) + if [ ${#wheels[@]} -eq 0 ]; then + echo "::error::no emscripten wheel was produced"; exit 1 + fi + for w in "${wheels[@]}"; do + echo "checking $w" + case "$w" in + *pyemscripten_2025_0_wasm32.whl) ;; + *) echo "::error::$w is not tagged pyemscripten_2025_0_wasm32"; exit 1 ;; + esac + done + python -m twine check rust/target/wheels/*.whl + - uses: actions/upload-artifact@v4 with: name: perspective-python-dist-wasm32-emscripten-${{ matrix.python-version }} @@ -441,7 +459,7 @@ jobs: arch: - x86_64 python-version: - - 3.11 + - "3.13" node-version: [22.x] steps: - name: Checkout @@ -996,7 +1014,7 @@ jobs: - uses: actions/download-artifact@v4 with: - name: perspective-python-dist-wasm32-emscripten-3.11 + name: perspective-python-dist-wasm32-emscripten-3.13 - uses: actions/download-artifact@v4 with: diff --git a/package.json b/package.json index b255dbb4bf..04ecacdf03 100644 --- a/package.json +++ b/package.json @@ -15,7 +15,7 @@ "type": "module", "emscripten": "4.0.9", "llvm": "17.0.6", - "pyodide": "0.29.3", + "pyodide": "0.29.4", "engines": { "node": ">=16 <24" }, diff --git a/rust/perspective-python/build.mjs b/rust/perspective-python/build.mjs index a4befb5d79..08af760155 100644 --- a/rust/perspective-python/build.mjs +++ b/rust/perspective-python/build.mjs @@ -29,9 +29,11 @@ if (!!process.env.PSP_DEBUG) { flags = ""; } -const python_version = process.env.PSP_PYTHON_VERSION || "3.12"; const is_pyodide = !!process.env.PSP_PYODIDE; +const python_version = + process.env.PSP_PYTHON_VERSION || (is_pyodide ? "3.13" : "3.12"); + const version = pkg.version; fs.mkdirSync(`./perspective_python-${version}.data`, { recursive: true }); @@ -47,6 +49,8 @@ if (is_pyodide) { fs.readFileSync(path.resolve(__dirname, "../../package.json")), ); emsdk_prefix = `cd ${emsdkdir} && . ./emsdk_env.sh && ./emsdk activate ${emscripten} && cd ${cwd} && `; + env.MATURIN_PYEMSCRIPTEN_PLATFORM_VERSION = + process.env.MATURIN_PYEMSCRIPTEN_PLATFORM_VERSION || "2025_0"; } // if not windows diff --git a/rust/perspective-python/pyproject.toml b/rust/perspective-python/pyproject.toml index d5edcb67d0..2af41b01bf 100644 --- a/rust/perspective-python/pyproject.toml +++ b/rust/perspective-python/pyproject.toml @@ -11,7 +11,7 @@ # ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ [build-system] -requires = ["maturin>=1.4,<2.0"] +requires = ["maturin>=1.13.3,<2.0"] build-backend = "maturin" [project] @@ -19,7 +19,8 @@ name = "perspective-python" requires-python = ">=3.9" dynamic = ["version"] dependencies = [] -license = { file = "LICENSE.md" } +license = "Apache-2.0" +license-files = ["LICENSE.md"] classifiers = [ "Development Status :: 5 - Production/Stable", "Programming Language :: Rust", @@ -29,6 +30,7 @@ classifiers = [ "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", "Framework :: Jupyter :: JupyterLab", "Framework :: Jupyter :: JupyterLab :: 3", "Framework :: Jupyter :: JupyterLab :: Extensions", diff --git a/rust/perspective-python/requirements.txt b/rust/perspective-python/requirements.txt index 6bd19d03a3..3e67c6c09e 100644 --- a/rust/perspective-python/requirements.txt +++ b/rust/perspective-python/requirements.txt @@ -4,7 +4,7 @@ Faker==26.0.0 ipywidgets==8.1.3 jupyterlab_git==0.50.1 jupyterlab==4.2.3 -maturin==1.10.2 +maturin==1.14.1 numpy==2.2.6 packaging==24.1 pandas==2.3.0 diff --git a/tools/scripts/workspace.mjs b/tools/scripts/workspace.mjs index ee9bdfb854..90657a2fc0 100644 --- a/tools/scripts/workspace.mjs +++ b/tools/scripts/workspace.mjs @@ -42,7 +42,7 @@ export function getRustWheelsDir() { export function getEmscriptenWheelPath() { const pspVersion = getWorkspacePackageJson().version.replace("-", "."); - const wheeljunk = "cp311-abi3-emscripten_4_0_9_wasm32"; + const wheeljunk = "cp311-abi3-pyemscripten_2025_0_wasm32"; return path.join( rustWheelsDir, `perspective_python-${pspVersion}-${wheeljunk}.whl`,