github skuznetsov/depyo.js v1.2.2

4 hours ago

depyo.js v1.2.2 — issue #10 fix

Single bugfix release. Closes #10.

What was broken

A list literal compiled by CPython 3.10+ would decompile to a chain of subscripts like [][a][1][2]...[30] instead of the original [a, 1, 2, ..., 30], but only if the literal was large enough and not all-constant.

Root cause

CPython's compiler (Python/compile.c, around STACK_USE_GUIDELINE) has two paths for list literals:

  • Small / all-constant: emit one BUILD_LIST N with all elements already on the stack.
  • Big + non-constant: emit BUILD_LIST 0 to push an empty list, then N×LIST_APPEND to fill it one element at a time.

depyo's processListAppend in lib/handlers/collections_update.js only had two branches: comprehension → build ASTComprehension, otherwise → build ASTSubscr. The "otherwise" branch implicitly assumed LIST_APPEND only fires inside comprehensions. The big-literal path violates that assumption, so each LIST_APPEND was reinterpreted as a subscript on whatever was below it.

The fix

Added a third branch: when the stack top is already an ASTList, mutate it in place (list.values.push(value)) and leave it on the stack for the next LIST_APPEND (or the final STORE_*). Comprehension and ASTSubscr paths are unchanged.

bd8b46e — fix: LIST_APPEND on bare BUILD_LIST 0 — reconstruct list literal (issue #10)

Sibling audit (no fix needed)

Confirmed by reading handleSetAddA (collections_update.js:7) and handleMapAddA (subscript_slice.js:12): both already mutate the container in place on their non-comprehension branch. The bug was unique to LIST_APPEND. A guard fixture issue10_big_set_dict.py pins that correct behavior across 3.10–3.14 so any future "unify the three handlers" refactor will catch a regression.

Regression coverage

test/modern_features/issue10_big_list.py and test/modern_features/issue10_big_set_dict.py compiled and snapshotted against Python 3.10, 3.11, 3.12, 3.13, and 3.14. Full suite: 1202/1202, sentinel gate clean.

6b89f05 — test: extend issue #10 coverage — 3.10–3.14 + big_set/dict sibling guard

Install

npm install -g depyo
# or
npx depyo <file.pyc>

The Python port skuznetsov/depyo.py ships the same fix at the same version.

Don't miss a new depyo.js release

NewReleases is sending notifications on new releases.