Skip to content

Embed SymPy (Pyodide + Brython engines), rewrite parsers, modernize tooling - #4

Open
zalo wants to merge 2 commits into
masterfrom
modernize-embedded-sympy
Open

Embed SymPy (Pyodide + Brython engines), rewrite parsers, modernize tooling#4
zalo wants to merge 2 commits into
masterfrom
modernize-embedded-sympy

Conversation

@zalo

@zalo zalo commented Aug 13, 2026

Copy link
Copy Markdown
Owner

Modernizes Symplex end-to-end and embeds SymPy 1.14 directly in the extension — no Python installation required. Two commits, matching the changelog:

v0.1.0 — Embedded SymPy, parser rewrite, tooling

Embedded engine (default): SymPy 1.14.0 runs inside the extension via Pyodide (CPython on WebAssembly) on a worker thread — timeouts hard-kill wedged evaluations, idle workers shut down after 5 minutes (~110 MB reclaimed), and wheels/ ships the SymPy/mpmath wheels for fully-offline use (CDN fallback otherwise). The old subprocess mode survives as "symplex.engine": "system", now with accumulated stream reads, spawn-error handling, and a timeout that actually fires (faulthandler.dump_traceback_later without exit=True only ever printed).

Parser fixes (each had a test-verified failing case before):

  • JS/TS (rewritten on the typed AST API, no more positional getChildAt): pow(x+1,2)x + 1**2, a % bab, foo()fo), second declarators dropped, type annotations → (), non-Math property accesses silently vanishing, trailing \r on every result.
  • Python (whole-word substitution, single pass): x replaced inside exp(...), infinite loop on x = x + 1 (froze the extension host), crash on bare final expressions, empty output on trailing newlines.
  • "javscript" typo that generated undefinedresult = ..., output truncated by the wrong variable's length, chunked-stdout JSON parses.

Tooling: TypeScript 5.9 (runtime dep pinned <7 — the Go-native TS 7 dropped ts.createSourceFile), ESLint 9 replacing tslint, engines ^1.90 matched to @types/vscode, broken REPLACEWITHTHEABOVETODEBUGPARSING menu clause and empty-snippets contribution removed, npm test (30 tests incl. end-to-end embedded evaluation).

v0.2.0 — Brython engine

New opt-in "symplex.engine": "embedded-brython": SymPy on Brython (Python transpiled to JS) in a worker thread. Ships the patched Brython build in vendor/brython — stock releases up to 3.14.3 silently miscompute SymPy results (Pow(3,-1)3); fixes are upstream in brython-dev/brython#2912. The worker shims a minimal browser environment plus an fs-backed synchronous XHR for imports; npm run fetch-brython-libs extracts sympy/mpmath from the same wheels the Pyodide engine uses.

Measured head-to-head (same machine): Pyodide ~1s cold / near-instant warm / ~220 MB resident; Brython ~8s cold / ~0.3s warm / ~640 MB resident. Pyodide therefore stays the default.

Validation

  • npm test: 30/30 (converter unit tests + Pyodide and Brython end-to-end SymPy evaluations).
  • vsce package succeeds (21 MB with both engines and offline wheels).
  • npm run lint clean.

🤖 Generated with Claude Code

zalo and others added 2 commits August 13, 2026 10:58
- SymPy 1.14 runs inside the extension via Pyodide (CPython on WASM) on
  a worker thread with timeouts, idle shutdown and crash recovery; the
  old python-subprocess mode remains as 'symplex.engine': 'system' with
  proper stream handling and a real timeout (dump_traceback_later
  without exit=True never actually stopped anything).
- JavaScript/TypeScript converter rewritten on the typed AST API: fixes
  pow() precedence, % and ** operators, zero-argument calls,
  multi-declarator statements, type annotations, Math.PI/Math.E; and
  unsupported syntax now yields a readable error instead of silently
  corrupted output ('a % b' used to become 'ab').
- Python converter rewritten with whole-word substitution: fixes
  variable names replaced inside other identifiers (x inside exp), the
  infinite loop on self-referential assignments that froze the editor,
  and crashes on bare final expressions.
- Tooling: TypeScript 5, ESLint 9 (tslint removed), engines ^1.90
  matched to @types/vscode, dead snippets/menu contributions removed,
  tests (npm test) covering every fixed bug plus an end-to-end
  embedded-SymPy evaluation.

Note: package-lock.json lands in the next commit together with the
final dependency set.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
New optional engine 'symplex.engine': 'embedded-brython' running SymPy
1.14 on Brython (Python transpiled to JavaScript) in a worker thread —
no Python installation required.

- vendor/brython holds a patched Brython build (see
  vendor/brython/README.md): stock releases up to 3.14.3 silently
  miscompute SymPy results; the fixes are upstream in
  brython-dev/brython#2912. Do not replace with a CDN copy until that
  is merged and released.
- The worker shims a minimal browser environment (Brython targets
  browsers) and a filesystem-backed synchronous XMLHttpRequest that
  serves module imports and unicode.txt from vendor/brython.
- 'npm run fetch-brython-libs' extracts the sympy/mpmath sources into
  vendor/brython/lib (git-ignored) from the same wheels the Pyodide
  engine uses.
- Engines now share the WorkerEngine harness (timeout, idle shutdown,
  crash recovery).

Measured against Pyodide on the same machine: ~8s cold start vs ~1s,
~0.3s warm evaluations vs near-instant, ~640 MB resident vs ~220 MB —
so Pyodide stays the default; Brython is opt-in (its lightness applies
to browser downloads, not to a local extension host).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant