Skip to content

compat.pocketpy 2.2.0: PocketPy 2, a small embeddable Python interpreter (MIT) - #620

Merged
Sunrisepeak merged 3 commits into
mainfrom
compat-pocketpy
Oct 28, 2026
Merged

Sunrisepeak merged 3 commits into
mainfrom
compat-pocketpy

Conversation

@Sunrisepeak

@Sunrisepeak Sunrisepeak commented Oct 28, 2026 •

Copy link
Copy Markdown
Member

PocketPy 2.2.0 is a Python 3.x interpreter in C11 with no dependencies.
Built from the tag archive: every src/**/*.c (CMake's POCKETPY_SRC; the
checked-in _generated.c carries the pure-Python standard library), each
compiled on its own as upstream's build.sh does, -std=gnu11.

The PK_ENABLE_* values are those config.h gives a consumer that defines
none (what a consumer's <pocketpy.h> reads): OS on, THREADS off (CMake's
threads build compiles only as its unity build: time.c calls
c11_thrd__yield without its header), DLL off. Two upstream options are on:
DETERMINISM with -ffp-contract=off, as CMake builds it, and WATCHDOG, since
pocketpy.h declares py_watchdog_begin/end unconditionally but they exist
only with it. NDEBUG follows the profile, for library and consumer alike.
-lm on Linux; ws2_32 and _CRT_SECURE_NO_WARNINGS on Windows. The same
sources and flags on Linux, macOS, Windows and wasm32-emscripten.

The member tests/examples/pocketpy: version and configuration, exec and
eval with ints, floats, strings and bools read back, a dict and a list
walked, a bound C function with its argument checks, syntax and runtime
errors, a raise and runaway recursion each reported with its message and
the VM going on, the watchdog ending an endless loop, json, math and
collections, deterministic float values, code re-run in one VM, a second
VM and py_resetvm.

One upstream fix, applied in install() with a checked match count: pocketpy de8351ed (on main since 2026-09-06, after the 2.2.0 tag). An exception's recorded traceback frames carry locals/globals values only the debugger fills in, and the garbage collector marks them unconditionally, so a collection while an exception object is alive reads uninitialised memory and can crash (upstream's own tests/901_array2d_extra1.py does, built as build.sh builds it). The fix sets both to nil. The member keeps 400 exceptions alive across collections after garbage has dirtied the heap.

Tested locally (mcpp 2026.10.27.1): mcpp test -p pocketpy-tests with gcc@16.1.0 (dev and release), llvm@23.1.3, and emsdk@6.0.9 --target wasm32-emscripten under node: every check passes. Upstream's tests/*.py (87, from source and compiled to .pyc) pass on a host built over this package in mcpplibs/pocketpy-m.

…ter (MIT)

PocketPy 2.2.0 is a Python 3.x interpreter in C11 with no dependencies.
Built from the tag archive: every src/**/*.c (CMake's POCKETPY_SRC; the
checked-in _generated.c carries the pure-Python standard library), each
compiled on its own as upstream's build.sh does, -std=gnu11.

The PK_ENABLE_* values are those config.h gives a consumer that defines
none (what a consumer's <pocketpy.h> reads): OS on, THREADS off (CMake's
threads build compiles only as its unity build: time.c calls
c11_thrd__yield without its header), DLL off. Two upstream options are on:
DETERMINISM with -ffp-contract=off, as CMake builds it, and WATCHDOG, since
pocketpy.h declares py_watchdog_begin/end unconditionally but they exist
only with it. NDEBUG follows the profile, for library and consumer alike.
-lm on Linux; ws2_32 and _CRT_SECURE_NO_WARNINGS on Windows. The same
sources and flags on Linux, macOS, Windows and wasm32-emscripten.

The member tests/examples/pocketpy: version and configuration, exec and
eval with ints, floats, strings and bools read back, a dict and a list
walked, a bound C function with its argument checks, syntax and runtime
errors, a raise and runaway recursion each reported with its message and
the VM going on, the watchdog ending an endless loop, json, math and
collections, deterministic float values, code re-run in one VM, a second
VM and py_resetvm.
…ads uninitialised

install() applies pocketpy de8351ed (on main since 2026-09-06, after the
2.2.0 tag) with a checked match count: an exception's recorded traceback
frames carry `locals` and `globals` values only the debugger fills in, and
the garbage collector marks them unconditionally, so a collection while an
exception object is alive reads uninitialised memory and can crash
(upstream's own tests/901_array2d_extra1.py does, built as build.sh builds
it). The fix sets both to nil when a frame is recorded. The member keeps
400 exceptions alive across collections after garbage has dirtied the heap.
CMake's default is a unity build of all of POCKETPY_SRC in one group, and
the release's pocketpy.c is the same sources amalgamated; the generated
pocketpy_unity.c includes the 84 files in CMake's GLOB_RECURSE order. The
sources rely on it: with NDEBUG, PK_INLINE marks functions the headers
declare and other files call `inline`, and clang emits no definition of
them for the MSVC ABI, so compiled one by one the release profile left
PyObject__userdata, pk_typeinfo, c11__bit_length and others undefined on
Windows (found by pocketpy-m's CI). Calls across files now inline as in
upstream's build. Tested again with GCC (dev, release), LLVM (release) and
wasm32-emscripten (release).
@Sunrisepeak
Sunrisepeak merged commit e237556 into main Oct 28, 2026
18 checks passed
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