QuantEcon / QuantEcon/QuantEcon.py

WASM: document browser limitations and raise helpful platform-specific errors

Open
#931 2 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

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

Description

[!NOTE]
Updated 2026-09-09. Item 1 is withdrawn — it was wrong. Network calls work in the browser; @oyamad demonstrated both call paths in xeus-python on 2026-09-06 and the reasoning is in the comment below. PR #948 was built on the old text before anyone tested it. Item 3 is moved out of this issue (no WASM rationale left, and it is entangled with the util/notebooks.py deprecation question for 0.12.0). Items 2 and 4 stand and are unchanged in substance. The 2026-08-21 revision and the original text are in the edit history.

Part of #925 (Phase 1). Documentation and error-message work — no behaviour changes on native platforms.

Items

  • Network utilities fail in the browser. Withdrawn 2026-09-09 — the premise was false. The original text claimed fetch_nb_dependencies and the GameTracer .gam URL loaders "perform socket-level HTTP, which does not exist in WASM", and that JS-fetch-backed shims are "kernel-specific and not guaranteed in xeus-python". Both calls in fact work in xeus-python today: urllib3 has shipped native Emscripten support since 2.2.0 and enables it automatically when sys.platform is emscripten, substituting EmscriptenHTTPConnection over XMLHttpRequest (or fetch on a worker thread for streaming), and requests sits on urllib3. emscripten-forge reached the same conclusion months ago and retired requests-wasm-polyfill as redundant (emscripten-forge/recipes#782). Do not add a sys.platform == "emscripten" guard here — that condition is exactly what switches urllib3 onto its browser transport, so the guard would fire precisely when the network path is being enabled. If a friendlier error is still wanted later, the shape to aim for is wrapping a failure that actually occurs rather than refusing before trying, and it is better attempted once #950 / #933 give us a browser kernel where a real failure can be observed.
  • probvec docstring. parallel=True (the default) silently executes serially on Emscripten. Two numba emscripten patches produce this: patch 0007 falls back from the target='parallel' ufunc target to 'cpu' (the path probvec takes), and patch 0010 (emscripten-forge/recipes#6293, merged 2026-08-18, shipped as numba 0.67.0 build 1) compiles @njit(parallel=True) serially and forces NUMBA_NUM_THREADS=1. A one-line note keeps the documented contract honest. This is the part of PR #948 that should land — it is correct and independent of everything above.
  • Consider demoting requests from a hard dependency to an optional extra. Moved out of this issue and out of #925 on 2026-09-09. requests resolves for the browser and now demonstrably works there, so this is ordinary dependency hygiene rather than browser work. It is also entangled with the separate question of deprecating quantecon/util/notebooks.py in 0.12.0 and dropping requests altogether; if that goes ahead this item is moot. It should be tracked with that decision, not here.
  • A short "QuantEcon.py in the browser" docs page. The supported stack (JupyterLite + xeus-python + emscripten-forge); what works (sourced from the per-function results table #928 is meant to record — note that this now includes the network utilities); what does not work yet (the jitted-generator hang, #927, and the warm-cache cache=True failure, #944); single-threaded execution — all Numba parallelism is silently serialised in the browser (guvectorize target='parallel' via patch 0007; @njit(parallel=True) / prange and NUMBA_NUM_THREADS=1 via patch 0010); and the wasm32 limits (coordinate with #929).

Testing note

Smoke tests for this issue must assert capabilities, not guards. PR #948's two Emscripten-gated tests asserted that our own sys.platform branch raises OSError — which the new code did unconditionally — so they would have passed in the browser and locked the defect in. Assert what the platform can actually do (from_url returns a 3-player game) so the test is able to disagree with us.

Related

  • PR #948 — implements the withdrawn item 1; needs cutting back to the probvec docstring note. Hold the rework until the util/notebooks.py deprecation question settles
  • #950 — QuantEcon-hosted JupyterLite testbed; the place a claim like item 1 should have been checked in seconds, and where the docs page's "what works" list can be verified
  • #928 — Phase 0 smoke checklist; its per-function results table is the source for the "what works" section of the docs page
  • #927 — jitted generators hang on first call in the browser, so support_enumeration and vertex_enumeration never return (LAPACK itself is verified working); no upstream report yet. The docs page should list both as not working
  • #944 — on a warm session, a cache=True caller whose callee was restored from the persistent cache fails with RuntimeError: no compiled object yet; reported upstream as emscripten-forge/recipes#6309 (open); decision is to wait for upstream
  • #926 / PR #937 — merged 2026-09-09; gini_coefficient is now the O(n log n) closed form, so the browser no longer runs a serial O(n²) loop
  • #930 / PR #943 — import time: patch 0007 also disables cache=True for @vectorize / @guvectorize, so the four eagerly compiled gufuncs recompile every session
  • #929 — wasm32 limits (32-bit default integer, comb_jit / simplex_grid boundary, 2–4 GB memory cap); documentation-only, and its second task hands the user-facing wording to this issue
  • ci/wasm/smoke_test.py — on main since PR #938. No browser job runs it yet; that runner is #933

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 the probvec entry point and the existing ci/wasm/smoke_test.py, then review the per-function results table from #928 and the wasm32 limits in #929. Add the Emscripten serial-execution note and a short browser documentation page covering supported components, working and unavailable features, threading limits, and wasm32 constraints. Verify capabilities rather than platform guards, including the browser testbed in #950.

Written by the indexing model from the issue text.

Assessment

Tech stack
jupyter, python, wasm
Domain
documentation, testing, web-dev
Issue type
Documentation
Difficulty
3/5
Estimated time
1-2 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
72/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.