QuantEcon / QuantEcon/QuantEcon.py

WASM: contribute a quantecon recipe to emscripten-forge

Open
#932 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

infrastructure upstream
Dominant language
Python
Stars
2.4k
Forks
2.3k
Avg merge
3d 3h
Merged PRs (30d)
3

Description

[!NOTE]
Updated 2026-08-21. The original Goal treated this recipe as what makes quantecon installable in JupyterLite; that is already true without it — quantecon is noarch: python on conda-forge, JupyterLite deployments resolve conda-forge alongside emscripten-forge-4x by default, the kernel environment merged in PR #938 (ci/wasm/environment.yml) installs it that way, and import quantecon has run in the browser (#927, emscripten-forge/recipes#6309). The body below reframes the recipe's value as a trimmed browser payload plus channel co-location with numba, makes the acceptance criteria recipe-specific, and updates the sequencing (the gini_coefficient gate became the O(n log n) rewrite in PR #937, and out-of-the-box use also waits on two upstream Numba fixes). The original text is preserved in the edit history.

Part of #925 (Phase 2 — distribution).

Goal

Contribute recipes/recipes_emscripten/quantecon/recipe.yaml to emscripten-forge/recipes so that JupyterLite deployments get a WASM-trimmed quantecon build from emscripten-forge-4x instead of the conda-forge noarch package.

Installability itself is not the motivation. quantecon 0.11.4 ships on conda-forge as noarch/quantecon-0.11.4-pyhd8ed1ab_0.conda (267 KB); emscripten-forge installs all noarch packages from conda-forge, and the default channel pair (emscripten-forge-4x, then conda-forge) is consulted both at deployment build time and by the %mamba install magic (mambajs). The Phase 0 environment now on main (ci/wasm/environment.yml, PR #938) lists quantecon directly against that pair, and import quantecon has been run in the xeus-python kernel (#927 comments; the emscripten-forge/recipes#6309 traceback). %mamba install quantecon has not yet been exercised in a browser, but it solves over the same channels and is expected to resolve the conda-forge build too. No quantecon recipe exists in emscripten-forge/recipes today.

What the recipe adds:

  • A smaller browser payload. Roughly a third of the installed package (about 400 KB of ~1.2 MB) is the 40 files under the subpackage tests/ directories (32 test_*.py, 3 .gam, 5 __init__.py). pyproject.toml [tool.flit.sdist] excludes only quantecon/tests/ and quantecon/util/tests, so the subpackage tests ride along in the sdist and into every downstream build. A recipe that excludes **/tests/** and sets skip_pyc_compilation — exactly what the sympy recipe does, and sympy is likewise noarch-only on conda-forge — removes that.
  • Channel co-location. emscripten-forge-4x is listed before conda-forge by default, so an emscripten-forge build shadows the conda-forge package automatically and sits next to the emscripten-forge numba build it runs on, giving one place for any WASM-specific pins.

An alternative for the payload half is to trim at source — exclude the subpackage tests/ directories from the sdist in pyproject.toml — which shrinks the conda-forge noarch build without any emscripten-forge recipe. If payload size turns out not to matter, this issue can be deprioritised.

Approach

Model on the existing pure-Python recipes: pip-install from a source tarball (the sympy recipe uses the GitHub tag archive; pytensor-base and numba use the PyPI sdist — either works for quantecon), exclude tests from the payload, and set skip_pyc_compilation (payload size is a first-class concern in the browser; sympy and numba both do this). Run-dependencies: python, numba, numpy, scipy, sympy, requests — if #931 demotes requests to an optional extra, it drops out here too. The pytensor-base recipe is the precedent for a Numba-downstream package; quantecon's floor (numba>=0.56.0 on main, >=0.49.0 in the released 0.11.4) is far below the emscripten-forge numba (0.67.0), so no pin gymnastics are needed.

Recipes carry a tests: block: sympy's is an echo "FIXME:" placeholder pending emscripten-forge/recipes#4364, while pytensor-base uses pytester with a test_import_pytensor_base.py, so the quantecon recipe will need a test_import_quantecon.py. The merged ci/wasm/environment.yml is the ready-made environment to test the recipe against.

The conda recipe is the right primary vehicle: jupyterlite-xeus's experimental pip: section does not resolve dependencies, so the (already pure) PyPI wheel is only a fallback path. Deployments already resolve conda-forge (where quantecon is noarch) alongside emscripten-forge-4x, so the recipe's advantage is the trimmed payload and co-location, not resolvability.

Sequencing

Best contributed after the Phase 1 library fixes (at minimum the gini_coefficient O(n log n) rewrite, #926 / PR #937 — approved, awaiting merge) ship in a release after 0.11.4, so the first browser-installable quantecon works out of the box. Two further Phase 1 blockers are upstream rather than library-side and are addressed by emscripten-forge numba rebuilds, not by a quantecon release: #944 (a cache-miss cache=True caller linking a cache-restored callee fails with "no compiled object yet", so simplex_grid breaks on a warm cache; tracked as emscripten-forge/recipes#6309, decision 2026-08-21: wait for upstream) and #927 (jitted generators hang, so support_enumeration and vertex_enumeration never return; no upstream report yet). "Works out of the box" will lag until those land. Not hard-blocked on any of this — the recipe can track the current release and be version-bumped.

Acceptance criteria

  • Recipe merged in emscripten-forge/recipes, with a pytester test_import_quantecon.py
  • In a fresh JupyterLite xeus-python deployment on the default channel pair, quantecon resolves from emscripten-forge-4x rather than conda-forge noarch — both via the kernel environment.yml and via %mamba install quantecon — and import quantecon works there
  • The installed payload omits the subpackage tests/ directories and skips pyc compilation; size recorded against the 267 KB conda-forge artifact

Related

  • #928 / PR #938 (merged 2026-08-21) — ci/wasm/environment.yml installs the conda-forge noarch package on the default channel pair and seeds the recipe test; the harness's test_import_quantecon checks whichever build resolves
  • #933 — the CI job tests the released conda-forge quantecon until the package lands on emscripten-forge-4x; switch it over once this lands
  • #944 / emscripten-forge/recipes#6309 — cache=True chain failure (simplex_grid on a warm cache); blocks out-of-the-box use, not installation
  • #927 — jitted-generator hang (support_enumeration, vertex_enumeration); likewise an upstream blocker for out-of-the-box use
  • #926 / PR #937 — the library-side Phase 1 fix the first release needs
  • #931 — requests as an optional extra changes the recipe's run-dependencies
  • #934 — a live %mamba install quantecon in the demo notebook pulls the conda-forge noarch build until this lands

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with ci/wasm/environment.yml and the existing sympy and pytensor-base recipes in emscripten-forge/recipes, then inspect the quantecon source layout and dependencies. The work is complete when recipes/recipes_emscripten/quantecon/recipe.yaml includes the trimmed payload and pytester import test, resolves from emscripten-forge-4x in a fresh JupyterLite deployment, and omits subpackage tests while recording the installed size.

Written by the indexing model from the issue text.

Assessment

Tech stack
python, wasm
Domain
build-system, release
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
55/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.