Skip to content

Add tests and docs for local .whl packages under _static/ #14

Description

@cursor

Summary

Add build-time test coverage for the local Pyodide wheel workflow used by Rust/wasm Python binding projects:

.. py-repl::
   :packages: _static/wheels/myext-pyodide.whl
   :src: _static/bootstrap.py

The extension already passes :packages: through to <py-repl> — this issue adds regression tests and documentation, not new directive logic (Phase 0).

Motivation

  • Validates the Sphinx build pipeline: static wheel copied to output, HTML attributes correct, startup script + replay work together
  • Runtime micropip install depends on pyrepl-web resolving relative wheel paths: chrizzFTD/pyrepl-web#… (Issue A — link after filed)
  • Unblocks costa docs migration away from a custom costa_repl Sphinx extension

Note: Flat doc layouts (e.g. naming Name.html at the source root with pyrepl_doctest_blocks = "autodoc") already work for autodoc REPLs using PyPI packages= names. This issue targets the local wasm wheel path specifically.

Proposed implementation

1. Test fixture

Add a minimal pure-Python wheel:

tests/fixtures/wheels/pyrepl_test_pkg-1.0.0-py3-none-any.whl

Generate once from a tiny package and commit the artifact (valid PEP 427 zip; tests never run micropip).

2. New tests — tests/test_local_wheel.py

Test 1 — doctree (fast): :packages: emitted verbatim in HTML

.. py-repl::
   :packages: _static/wheels/pyrepl_test_pkg-1.0.0-py3-none-any.whl
   :no-header:

Assert: packages="_static/wheels/pyrepl_test_pkg-1.0.0-py3-none-any.whl" in doctree/HTML output.

Test 2 — full build: wheel copied to output tree

  • Copy fixture wheel → tmpdir/docs/_static/wheels/
  • Run sphinx-build
  • Assert (outdir / "_static/wheels/pyrepl_test_pkg-1.0.0-py3-none-any.whl").is_file()
  • Assert HTML contains the packages= attribute and pyrepl.js

Test 3 — costa-shaped integration build: :packages: + :src: + replay body

.. py-repl::
   :packages: _static/wheels/pyrepl_test_pkg-1.0.0-py3-none-any.whl
   :src: _static/bootstrap.py
   :repl-title: test
   :no-banner:

   >>> import pyrepl_test_pkg
   >>> pyrepl_test_pkg.ping()

Assert: wheel + bootstrap script in output; replay script under _static/pyrepl/; HTML has packages=, src=, and replay-src= together.

Test 4 — comma-separated packages (doctree):

.. py-repl::
   :packages: numpy, _static/wheels/pyrepl_test_pkg-1.0.0-py3-none-any.whl

3. Documentation

Add a Local Pyodide wheels section to README and docs/example.rst covering:

  • Wheel under html_static_path (typically _static/wheels/)
  • Stable filename alias in CI (copy versioned build artifact to a fixed docs name)
  • Project-specific :src: bootstrap for post-install import paths
  • Server MIME type for .whl (application/zip)

Out of scope (follow-up issues)

  • pyrepl_autodoc_packages — autodoc bootstrap override for non-PyPI wasm wheels (costa Phase 2)
  • Playwright / browser E2E test that micropip actually installs the wheel
  • Build-time path normalization for nested doc pages (docs/source/api/page.rst)

After pyrepl-web Issue A merges

  • Re-vendor pyrepl assets: python scripts/vendor_repl.py --branch <branch-with-fix>
  • Release patch version (e.g. 0.2.1)

Acceptance criteria

  • Fixture wheel committed under tests/fixtures/wheels/
  • ≥3 new tests in tests/test_local_wheel.py pass on Python 3.12–3.14 CI matrix
  • README + docs example for local wheel pattern
  • Re-vendor + release after pyrepl-web fix lands

Related

  • pyrepl-web: resolve relative wheel paths before micropip.install() (Issue A)
  • costa: Phase 1 docs migration to sphinx-pyrepl-web

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions