From da45d815f34ea245de668908da240b2d54508e29 Mon Sep 17 00:00:00 2001 From: ndonkoHenri Date: Sat, 4 Jul 2026 12:04:09 +0200 Subject: [PATCH 1/6] fix: stop stamping PYTHONINSPECT into the host process environment MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit All four platform implementations set PYTHONINSPECT=1 among the env vars they setenv() before Py_Initialize. The variable has no effect on the embedded interpreter itself — nothing in the embedded lifecycle runs pymain, which is the only consumer of Py_InspectFlag — but because the vars are written into the real process environment, every child process the app spawns inherits it. That inheritance becomes actively harmful with multiprocessing child interception (dart_bridge >= 1.5.0, flet-dev/flet#4283): a serviced worker child IS a real interpreter run through Py_Main, and an inherited PYTHONINSPECT would hold it open in interactive mode after its -c command completes instead of exiting. It equally affects any python interpreter a user launches via subprocess from a packaged app. dart_bridge's serious_python_main also unsets the variable defensively (apps may run against an older serious_python), but the right fix is to stop leaking it in the first place. --- src/serious_python_android/lib/serious_python_android.dart | 1 - src/serious_python_darwin/lib/serious_python_darwin.dart | 1 - src/serious_python_linux/lib/serious_python_linux.dart | 1 - src/serious_python_windows/lib/serious_python_windows.dart | 1 - 4 files changed, 4 deletions(-) diff --git a/src/serious_python_android/lib/serious_python_android.dart b/src/serious_python_android/lib/serious_python_android.dart index 3b3f779b..f2cf4f21 100644 --- a/src/serious_python_android/lib/serious_python_android.dart +++ b/src/serious_python_android/lib/serious_python_android.dart @@ -116,7 +116,6 @@ class SeriousPythonAndroid extends SeriousPythonPlatform { } final env = { - 'PYTHONINSPECT': '1', 'PYTHONDONTWRITEBYTECODE': '1', 'PYTHONNOUSERSITE': '1', 'PYTHONUNBUFFERED': '1', diff --git a/src/serious_python_darwin/lib/serious_python_darwin.dart b/src/serious_python_darwin/lib/serious_python_darwin.dart index 4e8cb76f..9b8ef7c0 100644 --- a/src/serious_python_darwin/lib/serious_python_darwin.dart +++ b/src/serious_python_darwin/lib/serious_python_darwin.dart @@ -55,7 +55,6 @@ class SeriousPythonDarwin extends SeriousPythonPlatform { ]; final env = { - 'PYTHONINSPECT': '1', 'PYTHONDONTWRITEBYTECODE': '1', 'PYTHONNOUSERSITE': '1', 'PYTHONUNBUFFERED': '1', diff --git a/src/serious_python_linux/lib/serious_python_linux.dart b/src/serious_python_linux/lib/serious_python_linux.dart index 0c2a39cc..ea9c3147 100644 --- a/src/serious_python_linux/lib/serious_python_linux.dart +++ b/src/serious_python_linux/lib/serious_python_linux.dart @@ -48,7 +48,6 @@ class SeriousPythonLinux extends SeriousPythonPlatform { ]; final env = { - 'PYTHONINSPECT': '1', 'PYTHONDONTWRITEBYTECODE': '1', 'PYTHONNOUSERSITE': '1', 'PYTHONUNBUFFERED': '1', diff --git a/src/serious_python_windows/lib/serious_python_windows.dart b/src/serious_python_windows/lib/serious_python_windows.dart index de0a6a8a..5c6861ba 100644 --- a/src/serious_python_windows/lib/serious_python_windows.dart +++ b/src/serious_python_windows/lib/serious_python_windows.dart @@ -46,7 +46,6 @@ class SeriousPythonWindows extends SeriousPythonPlatform { ]; final env = { - 'PYTHONINSPECT': '1', 'PYTHONDONTWRITEBYTECODE': '1', 'PYTHONNOUSERSITE': '1', 'PYTHONUNBUFFERED': '1', From bb96f7710f72de6ee053bdca14fb3660a7934495 Mon Sep 17 00:00:00 2001 From: ndonkoHenri Date: Sat, 4 Jul 2026 12:04:23 +0200 Subject: [PATCH 2/6] feat(darwin): keep-alive refs for dart_bridge 1.5.0 multiprocessing exports MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit dart_bridge 1.5.0 adds serious_python_is_mp_invocation / serious_python_main (flet-dev/flet#4283): the host app's main.swift dlsym's them before NSApplicationMain to detect CPython child command lines produced by multiprocessing's spawn machinery and service them as a plain headless interpreter instead of booting a second GUI instance. On Apple platforms dart_bridge is a static archive linked into the host executable, and both entry points are dlsym-only — there is no static call site anywhere, so the app link's -dead_strip would discard them. Extend the existing keep-alive block (which already protects serious_python_run and the DartBridge_* exports for Dart FFI's DynamicLibrary.process() lookups) with references to the two new symbols. This is belt-and-braces: dart_bridge 1.5.0 also marks its exports __attribute__((used)) (no-dead-strip at the atom level), but the keep-alive keeps working against toolchains or archives where that attribute is absent, and documents the dlsym contract in the one place Apple linkage is wired. --- .../serious_python_darwin/SeriousPythonPlugin.swift | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/serious_python_darwin/darwin/serious_python_darwin/Sources/serious_python_darwin/SeriousPythonPlugin.swift b/src/serious_python_darwin/darwin/serious_python_darwin/Sources/serious_python_darwin/SeriousPythonPlugin.swift index d676aa0b..4e851af1 100644 --- a/src/serious_python_darwin/darwin/serious_python_darwin/Sources/serious_python_darwin/SeriousPythonPlugin.swift +++ b/src/serious_python_darwin/darwin/serious_python_darwin/Sources/serious_python_darwin/SeriousPythonPlugin.swift @@ -15,6 +15,16 @@ private func _sp_run_keepalive(_ cfg: OpaquePointer?) -> Int32 private func _sp_init_keepalive(_ data: UnsafeMutableRawPointer?) -> Int @_silgen_name("DartBridge_EnqueueMessage") private func _sp_enqueue_keepalive(_ data: UnsafePointer?, _ len: Int) +// multiprocessing child-interception entry points (dart_bridge >= 1.5.0), +// dlsym'd by the host app's main.swift before NSApplicationMain. +@_silgen_name("serious_python_is_mp_invocation") +private func _sp_is_mp_keepalive( + _ argc: Int32, _ argv: UnsafeMutablePointer?>? +) -> Int32 +@_silgen_name("serious_python_main") +private func _sp_main_keepalive( + _ argc: Int32, _ argv: UnsafeMutablePointer?>? +) -> Int32 /// Thin Flutter plugin: surfaces the python.bundle resource path to Dart. /// All Python lifecycle now lives in `serious_python_run` @@ -39,6 +49,8 @@ public class SeriousPythonPlugin: NSObject, FlutterPlugin { _ = _sp_run_keepalive(nil) _ = _sp_init_keepalive(nil) _sp_enqueue_keepalive(nil, 0) + _ = _sp_is_mp_keepalive(0, nil) + _ = _sp_main_keepalive(0, nil) } } From e76960f662fb9e53c0fbcf26e61d4b2b158a539b Mon Sep 17 00:00:00 2001 From: ndonkoHenri Date: Sat, 4 Jul 2026 12:04:38 +0200 Subject: [PATCH 3/6] fix(darwin): re-extract dart_bridge.xcframework when its version changes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit prepare_macos.sh / prepare_ios.sh guarded the dart_bridge extraction with a bare directory-exists check, so once dist_* held an extracted dart_bridge.xcframework, a dart_bridge version bump kept staging the stale extraction from the previous version — the freshly downloaded zip in the version-keyed cache was never unpacked. (The Python dist half of the script already solved the identical problem with a .python_build_id marker.) Key the extraction the same way: a .dart_bridge_version marker next to the extracted xcframework, re-extracting (rm -rf + unzip) whenever it is missing or disagrees with the requested version. Also fold the duplicated "$python_full_version-$python_build_date" expression into a single pb_id variable used for both the cache dir and the dist marker. --- src/serious_python_darwin/darwin/prepare_ios.sh | 14 +++++++++----- src/serious_python_darwin/darwin/prepare_macos.sh | 14 +++++++++----- 2 files changed, 18 insertions(+), 10 deletions(-) diff --git a/src/serious_python_darwin/darwin/prepare_ios.sh b/src/serious_python_darwin/darwin/prepare_ios.sh index 279c99b8..49902602 100755 --- a/src/serious_python_darwin/darwin/prepare_ios.sh +++ b/src/serious_python_darwin/darwin/prepare_ios.sh @@ -15,7 +15,8 @@ cache_root="${FLET_CACHE_DIR:-$HOME/.flet/cache}" # date — e.g. a rebuild that only re-signs binaries) downloads fresh instead of # being served stale from the previous release's cache. dart-bridge stays # version-keyed (its re-releases bump the version). -pb_cache="$cache_root/python-build/v$python_full_version-$python_build_date" +pb_id="$python_full_version-$python_build_date" +pb_cache="$cache_root/python-build/v$pb_id" db_cache="$cache_root/dart-bridge/v$dart_bridge_version" mkdir -p "$pb_cache" "$db_cache" @@ -34,14 +35,13 @@ fi # 3.14 site-packages, which trips C-extension ABI errors ("unknown slot ID") at # import. The marker keys the extracted dist to the version + release date, so a # same-version re-release (new build date) also re-extracts. -build_id="$python_full_version-$python_build_date" marker="$dist/.python_build_id" -if [ ! -d "$dist" ] || [ "$(cat "$marker" 2>/dev/null)" != "$build_id" ]; then +if [ ! -d "$dist" ] || [ "$(cat "$marker" 2>/dev/null)" != "$pb_id" ]; then rm -rf "$dist" mkdir -p "$dist" tar -xzf "$python_ios_dist_path" -C "$dist" mv "$dist/python-stdlib" "$dist/stdlib" - echo "$build_id" > "$marker" + echo "$pb_id" > "$marker" fi # ---- flet-dev/dart-bridge (xcframework) ----------------------------------- @@ -55,7 +55,11 @@ if [ ! -f "$dart_bridge_path" ]; then mv "$dart_bridge_path.tmp" "$dart_bridge_path" fi -if [ ! -d "$dist/xcframeworks/dart_bridge.xcframework" ]; then +# Cache dart_bridge.xcframework by version; extract it if missing or if the version marker differs. +db_marker="$dist/xcframeworks/.dart_bridge_version" +if [ ! -d "$dist/xcframeworks/dart_bridge.xcframework" ] || [ "$(cat "$db_marker" 2>/dev/null)" != "$dart_bridge_version" ]; then + rm -rf "$dist/xcframeworks/dart_bridge.xcframework" mkdir -p "$dist/xcframeworks" unzip -q "$dart_bridge_path" -d "$dist/xcframeworks/" + echo "$dart_bridge_version" > "$db_marker" fi diff --git a/src/serious_python_darwin/darwin/prepare_macos.sh b/src/serious_python_darwin/darwin/prepare_macos.sh index 251c0a39..cd0f516b 100755 --- a/src/serious_python_darwin/darwin/prepare_macos.sh +++ b/src/serious_python_darwin/darwin/prepare_macos.sh @@ -16,7 +16,8 @@ cache_root="${FLET_CACHE_DIR:-$HOME/.flet/cache}" # date — e.g. a rebuild that only re-signs binaries) downloads fresh instead of # being served stale from the previous release's cache. dart-bridge stays # version-keyed (its re-releases bump the version). -pb_cache="$cache_root/python-build/v$python_full_version-$python_build_date" +pb_id="$python_full_version-$python_build_date" +pb_cache="$cache_root/python-build/v$pb_id" db_cache="$cache_root/dart-bridge/v$dart_bridge_version" mkdir -p "$pb_cache" "$db_cache" @@ -36,9 +37,8 @@ fi # 3.14 site-packages, which trips C-extension ABI errors ("unknown slot ID") at # import. The marker keys the extracted dist to the version + release date, so a # same-version re-release (new build date) also re-extracts. -build_id="$python_full_version-$python_build_date" marker="$dist/.python_build_id" -if [ ! -d "$dist" ] || [ "$(cat "$marker" 2>/dev/null)" != "$build_id" ]; then +if [ ! -d "$dist" ] || [ "$(cat "$marker" 2>/dev/null)" != "$pb_id" ]; then rm -rf "$dist" mkdir -p "$dist" tar -xzf "$python_macos_dist_path" -C "$dist" @@ -54,7 +54,7 @@ if [ ! -d "$dist" ] || [ "$(cat "$marker" 2>/dev/null)" != "$build_id" ]; then # unexpectedly" crash dialog. We don't need this launcher for embedded # use; libdart_bridge dlopens Python.framework's main binary directly. find "$dist/xcframeworks" -type d -name 'Python.app' -prune -exec rm -rf {} + - echo "$build_id" > "$marker" + echo "$pb_id" > "$marker" fi # ---- flet-dev/dart-bridge (xcframework, same archive for macOS + iOS) ----- @@ -68,7 +68,11 @@ if [ ! -f "$dart_bridge_path" ]; then mv "$dart_bridge_path.tmp" "$dart_bridge_path" fi -if [ ! -d "$dist/xcframeworks/dart_bridge.xcframework" ]; then +# Cache dart_bridge.xcframework by version; extract it if missing or if the version marker differs. +db_marker="$dist/xcframeworks/.dart_bridge_version" +if [ ! -d "$dist/xcframeworks/dart_bridge.xcframework" ] || [ "$(cat "$db_marker" 2>/dev/null)" != "$dart_bridge_version" ]; then + rm -rf "$dist/xcframeworks/dart_bridge.xcframework" mkdir -p "$dist/xcframeworks" unzip -q "$dart_bridge_path" -d "$dist/xcframeworks/" + echo "$dart_bridge_version" > "$db_marker" fi From 8ae7c56eb4602eb772d1d73776d04b9df9d2f683 Mon Sep 17 00:00:00 2001 From: ndonkoHenri Date: Sat, 4 Jul 2026 12:04:53 +0200 Subject: [PATCH 4/6] docs: 4.3.0 changelogs + desktop-only multiprocessing caveat MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Draft the 4.3.0 CHANGELOG sections across all five packages for the multiprocessing work (flet-dev/flet#4283): - serious_python: the dart_bridge 1.5.0 child-interception contract (serious_python_is_mp_invocation / serious_python_main, plus the _w wide-char variants on Windows) and the PYTHONINSPECT removal. - serious_python_darwin: dead-strip protection for the new exports and the version-keyed dart_bridge extraction in prepare_{macos,ios}.sh. - serious_python_windows / _linux: platform-specific consumption notes (wWinMain / main.cc dlopen; the Python 3.14 forkserver-default angle on Linux). - serious_python_android: PYTHONINSPECT removal only (no behavior change — Android doesn't support process spawning). Also scope the multiprocessing recommendation in docs/dedicated-data-channels.md: it applies to desktop hosts whose binary services the spawn re-exec protocol; iOS/Android forbid spawning child processes. The version numbers reference the upcoming dart_bridge 1.5.0 / serious_python 4.3.0 releases; the pubspec version bumps and the dart_bridge_version pin update land with the release commit once dart_bridge 1.5.0 is tagged. --- docs/dedicated-data-channels.md | 6 +++++- src/serious_python/CHANGELOG.md | 5 +++++ src/serious_python_android/CHANGELOG.md | 4 ++++ src/serious_python_darwin/CHANGELOG.md | 6 ++++++ .../Sources/serious_python_darwin/SeriousPythonPlugin.swift | 3 ++- src/serious_python_linux/CHANGELOG.md | 5 +++++ src/serious_python_windows/CHANGELOG.md | 5 +++++ 7 files changed, 32 insertions(+), 2 deletions(-) diff --git a/docs/dedicated-data-channels.md b/docs/dedicated-data-channels.md index aab40476..e6c4f5df 100644 --- a/docs/dedicated-data-channels.md +++ b/docs/dedicated-data-channels.md @@ -288,7 +288,11 @@ def _pump(self): Real parallelism comes from C extensions that **release the GIL during their work** — NumPy, PyTorch, Pillow, cryptography. Pure-Python CPU work serialises on the GIL; for that, use `multiprocessing` or -PEP 684 subinterpreters. +PEP 684 subinterpreters. Caveat: `multiprocessing` works in the embedded +runtime only on **desktop** hosts whose binary services the spawn re-exec +protocol via `serious_python_main` (dart_bridge >= 1.5.0, flet >= 0.86 build +template); it is not available on iOS/Android, where the OS forbids spawning +child processes. ### Dart side — Isolate scope diff --git a/src/serious_python/CHANGELOG.md b/src/serious_python/CHANGELOG.md index dfa7f545..0d475d2e 100644 --- a/src/serious_python/CHANGELOG.md +++ b/src/serious_python/CHANGELOG.md @@ -1,3 +1,8 @@ +## 4.3.0 + +* **Desktop multiprocessing support** ([flet-dev/flet#4283](https://github.com/flet-dev/flet/issues/4283)). `dart_bridge` **1.5.0** adds `serious_python_is_mp_invocation` / `serious_python_main` (+ `_w` wide-char variants on Windows): host apps call them first thing in `main` to detect CPython child command lines (`--multiprocessing-fork`, `-c "from multiprocessing..."` — spawn workers, the resource tracker, and the forkserver) and service them as a plain headless interpreter (`Py_Main`/`Py_BytesMain`, stable ABI) instead of re-launching the GUI. The exports rely on the `PYTHONHOME`/`PYTHONPATH` the parent already stamped process-wide. +* `PYTHONINSPECT=1` is no longer set by any platform implementation. It had no effect on the embedded interpreter, but it leaked into the process environment where any *real* interpreter child (e.g. a serviced multiprocessing worker) would inherit it and hang in interactive mode after its command completed. + ## 4.2.1 * **iOS/macOS:** ctypes packages that ship plain `.dylib` shared libraries (e.g. `llama-cpp-python`'s `libllama` / `libggml`) now load on the **iOS simulator**. Such `.dylib`s are now packaged as per-slice xcframeworks (previously only `.so` C-extensions were), so they carry a simulator slice instead of shipping the device build and failing `dlopen` with `incompatible platform (have 'iOS', need 'iOS-simulator')`; their install-name is preserved so multi-lib packages still resolve their sibling libs. See `serious_python_darwin` 4.2.1. diff --git a/src/serious_python_android/CHANGELOG.md b/src/serious_python_android/CHANGELOG.md index 369c0781..c7ca2299 100644 --- a/src/serious_python_android/CHANGELOG.md +++ b/src/serious_python_android/CHANGELOG.md @@ -1,3 +1,7 @@ +## 4.3.0 + +* `PYTHONINSPECT=1` is no longer set by any platform implementation. It had no effect on the embedded interpreter, but it leaked into the process environment where any *real* interpreter child (e.g. a serviced multiprocessing worker) would inherit it and hang in interactive mode after its command completed. No functional change on Android, which doesn't support process spawning. + ## 4.2.1 * Bump the bundled python-build snapshot to `20260701`; aligns with the `serious_python_*` 4.2.1 release. The Android runtimes are byte-identical to `20260630` (the release only rebuilds the iOS runtime). diff --git a/src/serious_python_darwin/CHANGELOG.md b/src/serious_python_darwin/CHANGELOG.md index 27a509b2..27e881bb 100644 --- a/src/serious_python_darwin/CHANGELOG.md +++ b/src/serious_python_darwin/CHANGELOG.md @@ -1,3 +1,9 @@ +## 4.3.0 + +* Bump `dart_bridge` to **1.5.0**: multiprocessing child-interception exports (`serious_python_is_mp_invocation` / `serious_python_main`), kept alive against the host link's `-dead_strip` both by `__attribute__((used))` in the archive and by keep-alive references in `SeriousPythonPlugin.swift`. See the `serious_python` 4.3.0 notes. +* `prepare_macos.sh` / `prepare_ios.sh`: the extracted `dart_bridge.xcframework` in `dist_*` is now keyed to the dart_bridge version (`.dart_bridge_version` marker) — previously a version bump kept staging the stale extraction from the earlier version. +* `PYTHONINSPECT=1` is no longer set by any platform implementation. It had no effect on the embedded interpreter, but it leaked into the process environment where any *real* interpreter child (e.g. a serviced multiprocessing worker) would inherit it and hang in interactive mode after its command completed. + ## 4.2.1 * Framework-ize ctypes `.dylib` shared libs (not just `.so` C-extensions) when syncing iOS site-packages, so `.dylib`-shipping packages (e.g. `llama-cpp-python`) load on the **iOS simulator** instead of failing `dlopen` with `incompatible platform (have 'iOS', need 'iOS-simulator')`. Each `.dylib` becomes a device+simulator xcframework + `.fwork` pointer, exactly like `.so`; unlike `.so` (whose id is rewritten to the framework path), the `.dylib` install-name is preserved so multi-lib packages resolve their sibling libs. The `.so` path is unchanged. diff --git a/src/serious_python_darwin/darwin/serious_python_darwin/Sources/serious_python_darwin/SeriousPythonPlugin.swift b/src/serious_python_darwin/darwin/serious_python_darwin/Sources/serious_python_darwin/SeriousPythonPlugin.swift index 4e851af1..bc9ba68e 100644 --- a/src/serious_python_darwin/darwin/serious_python_darwin/Sources/serious_python_darwin/SeriousPythonPlugin.swift +++ b/src/serious_python_darwin/darwin/serious_python_darwin/Sources/serious_python_darwin/SeriousPythonPlugin.swift @@ -15,7 +15,8 @@ private func _sp_run_keepalive(_ cfg: OpaquePointer?) -> Int32 private func _sp_init_keepalive(_ data: UnsafeMutableRawPointer?) -> Int @_silgen_name("DartBridge_EnqueueMessage") private func _sp_enqueue_keepalive(_ data: UnsafePointer?, _ len: Int) -// multiprocessing child-interception entry points (dart_bridge >= 1.5.0), + +// multiprocessing child-interception entry points, // dlsym'd by the host app's main.swift before NSApplicationMain. @_silgen_name("serious_python_is_mp_invocation") private func _sp_is_mp_keepalive( diff --git a/src/serious_python_linux/CHANGELOG.md b/src/serious_python_linux/CHANGELOG.md index 9b232ba5..89e73246 100644 --- a/src/serious_python_linux/CHANGELOG.md +++ b/src/serious_python_linux/CHANGELOG.md @@ -1,3 +1,8 @@ +## 4.3.0 + +* Bump `dart_bridge` to **1.5.0**: multiprocessing child-interception exports (`serious_python_is_mp_invocation` / `serious_python_main`), consumed by the flet build template's `main.cc` via `dlopen("libdart_bridge.so")`. Relevant on Linux since Python 3.14 made `forkserver` (which execs `sys.executable`) the default start method. See the `serious_python` 4.3.0 notes. +* `PYTHONINSPECT=1` is no longer set by any platform implementation. It had no effect on the embedded interpreter, but it leaked into the process environment where any *real* interpreter child (e.g. a serviced multiprocessing worker) would inherit it and hang in interactive mode after its command completed. + ## 4.2.1 * Bump the bundled python-build snapshot to `20260701`; aligns with the `serious_python_*` 4.2.1 release. The Linux runtimes are byte-identical to `20260630` (the release only rebuilds the iOS runtime). diff --git a/src/serious_python_windows/CHANGELOG.md b/src/serious_python_windows/CHANGELOG.md index efb47934..5886f34e 100644 --- a/src/serious_python_windows/CHANGELOG.md +++ b/src/serious_python_windows/CHANGELOG.md @@ -1,3 +1,8 @@ +## 4.3.0 + +* Bump `dart_bridge` to **1.5.0**: multiprocessing child-interception exports, including the Windows wide-char variants `serious_python_is_mp_invocation_w` / `serious_python_main_w` (→ `Py_Main`) consumed by the flet build template's `wWinMain`. See the `serious_python` 4.3.0 notes. +* `PYTHONINSPECT=1` is no longer set by any platform implementation. It had no effect on the embedded interpreter, but it leaked into the process environment where any *real* interpreter child (e.g. a serviced multiprocessing worker) would inherit it and hang in interactive mode after its command completed. + ## 4.2.1 * Bump the bundled python-build snapshot to `20260701`; aligns with the `serious_python_*` 4.2.1 release. The Windows runtimes are byte-identical to `20260630` (the release only rebuilds the iOS runtime). From 33592e81de541620d9f12850ac3655d10e64614e Mon Sep 17 00:00:00 2001 From: Feodor Fitsner Date: Wed, 8 Jul 2026 16:05:11 -0700 Subject: [PATCH 5/6] chore: bump python-build snapshot to 20260708 (dart_bridge 1.5.0, Pyodide 314.0.2) Regenerated via `dart run serious_python:gen_version_tables --release-date 20260708`. Delivers dart_bridge 1.5.0 with the multiprocessing child-interception exports; Pyodide for 3.14 bumped 314.0.1 -> 314.0.2. CPython versions unchanged (3.12.13 / 3.13.14 / 3.14.6). 4.3.0 changelogs updated to record the snapshot. --- src/serious_python/CHANGELOG.md | 1 + src/serious_python/lib/src/python_versions.dart | 8 ++++---- src/serious_python_android/CHANGELOG.md | 1 + .../android/python_versions.properties | 6 +++--- src/serious_python_darwin/CHANGELOG.md | 2 +- .../darwin/python_versions.properties | 6 +++--- src/serious_python_linux/CHANGELOG.md | 2 +- src/serious_python_linux/linux/python_versions.properties | 6 +++--- src/serious_python_windows/CHANGELOG.md | 2 +- .../windows/python_versions.properties | 6 +++--- 10 files changed, 21 insertions(+), 19 deletions(-) diff --git a/src/serious_python/CHANGELOG.md b/src/serious_python/CHANGELOG.md index 0d475d2e..b7dad49e 100644 --- a/src/serious_python/CHANGELOG.md +++ b/src/serious_python/CHANGELOG.md @@ -2,6 +2,7 @@ * **Desktop multiprocessing support** ([flet-dev/flet#4283](https://github.com/flet-dev/flet/issues/4283)). `dart_bridge` **1.5.0** adds `serious_python_is_mp_invocation` / `serious_python_main` (+ `_w` wide-char variants on Windows): host apps call them first thing in `main` to detect CPython child command lines (`--multiprocessing-fork`, `-c "from multiprocessing..."` — spawn workers, the resource tracker, and the forkserver) and service them as a plain headless interpreter (`Py_Main`/`Py_BytesMain`, stable ABI) instead of re-launching the GUI. The exports rely on the `PYTHONHOME`/`PYTHONPATH` the parent already stamped process-wide. * `PYTHONINSPECT=1` is no longer set by any platform implementation. It had no effect on the embedded interpreter, but it leaked into the process environment where any *real* interpreter child (e.g. a serviced multiprocessing worker) would inherit it and hang in interactive mode after its command completed. +* Bump the bundled python-build snapshot to `20260708`, which delivers `dart_bridge` **1.5.0**; Pyodide for 3.14 bumped **314.0.1 → 314.0.2**. Bundled Python versions are unchanged from 4.2.1 (**3.12.13 / 3.13.14 / 3.14.6**). ## 4.2.1 diff --git a/src/serious_python/lib/src/python_versions.dart b/src/serious_python/lib/src/python_versions.dart index d654a80b..f9fbf091 100644 --- a/src/serious_python/lib/src/python_versions.dart +++ b/src/serious_python/lib/src/python_versions.dart @@ -1,5 +1,5 @@ // GENERATED by `dart run serious_python:gen_version_tables` from python-build's -// manifest.json (release 20260701). Do not edit by hand — edit python-build's +// manifest.json (release 20260708). Do not edit by hand — edit python-build's // manifest.json, cut a release, bump `pythonReleaseDate`, and regenerate. const pythonVersionEnvironmentVariable = "SERIOUS_PYTHON_VERSION"; @@ -10,8 +10,8 @@ const pyodideVersionEnvironmentVariable = "SERIOUS_PYTHON_PYODIDE_VERSION"; const dartBridgeVersionEnvironmentVariable = "DART_BRIDGE_VERSION"; /// python-build release the bundled runtimes come from (YYYYMMDD). -const pythonReleaseDate = "20260701"; -const dartBridgeVersion = "1.4.1"; +const pythonReleaseDate = "20260708"; +const dartBridgeVersion = "1.5.0"; const defaultPythonVersion = "3.14"; class PythonRelease { @@ -56,7 +56,7 @@ const pythonReleases = { "3.14": PythonRelease( standaloneVersion: "3.14.6", standaloneReleaseDate: "20260623", - pyodideVersion: "314.0.1", + pyodideVersion: "314.0.2", pyodidePlatformTag: "pyemscripten-2026.0-wasm32", androidAbis: ["arm64-v8a", "x86_64", "armeabi-v7a"], prerelease: false, diff --git a/src/serious_python_android/CHANGELOG.md b/src/serious_python_android/CHANGELOG.md index c7ca2299..c44e2a94 100644 --- a/src/serious_python_android/CHANGELOG.md +++ b/src/serious_python_android/CHANGELOG.md @@ -1,6 +1,7 @@ ## 4.3.0 * `PYTHONINSPECT=1` is no longer set by any platform implementation. It had no effect on the embedded interpreter, but it leaked into the process environment where any *real* interpreter child (e.g. a serviced multiprocessing worker) would inherit it and hang in interactive mode after its command completed. No functional change on Android, which doesn't support process spawning. +* Bump the bundled python-build snapshot to `20260708` (`dart_bridge` **1.5.0**). The new multiprocessing child-interception exports are present in the runtime but not wired up on Android, which doesn't support process spawning. ## 4.2.1 diff --git a/src/serious_python_android/android/python_versions.properties b/src/serious_python_android/android/python_versions.properties index faf98a2e..c0f41b51 100644 --- a/src/serious_python_android/android/python_versions.properties +++ b/src/serious_python_android/android/python_versions.properties @@ -1,8 +1,8 @@ # GENERATED by `dart run serious_python:gen_version_tables` from -# python-build manifest.json (release 20260701). Do not edit by hand. +# python-build manifest.json (release 20260708). Do not edit by hand. default_python_version=3.14 -dart_bridge_version=1.4.1 -python_build_release_date=20260701 +dart_bridge_version=1.5.0 +python_build_release_date=20260708 3.12.full_version=3.12.13 3.12.android_abis=arm64-v8a,x86_64,armeabi-v7a 3.13.full_version=3.13.14 diff --git a/src/serious_python_darwin/CHANGELOG.md b/src/serious_python_darwin/CHANGELOG.md index 27e881bb..8b2f210a 100644 --- a/src/serious_python_darwin/CHANGELOG.md +++ b/src/serious_python_darwin/CHANGELOG.md @@ -1,6 +1,6 @@ ## 4.3.0 -* Bump `dart_bridge` to **1.5.0**: multiprocessing child-interception exports (`serious_python_is_mp_invocation` / `serious_python_main`), kept alive against the host link's `-dead_strip` both by `__attribute__((used))` in the archive and by keep-alive references in `SeriousPythonPlugin.swift`. See the `serious_python` 4.3.0 notes. +* Bump `dart_bridge` to **1.5.0** (python-build snapshot `20260708`): multiprocessing child-interception exports (`serious_python_is_mp_invocation` / `serious_python_main`), kept alive against the host link's `-dead_strip` both by `__attribute__((used))` in the archive and by keep-alive references in `SeriousPythonPlugin.swift`. See the `serious_python` 4.3.0 notes. * `prepare_macos.sh` / `prepare_ios.sh`: the extracted `dart_bridge.xcframework` in `dist_*` is now keyed to the dart_bridge version (`.dart_bridge_version` marker) — previously a version bump kept staging the stale extraction from the earlier version. * `PYTHONINSPECT=1` is no longer set by any platform implementation. It had no effect on the embedded interpreter, but it leaked into the process environment where any *real* interpreter child (e.g. a serviced multiprocessing worker) would inherit it and hang in interactive mode after its command completed. diff --git a/src/serious_python_darwin/darwin/python_versions.properties b/src/serious_python_darwin/darwin/python_versions.properties index faf98a2e..c0f41b51 100644 --- a/src/serious_python_darwin/darwin/python_versions.properties +++ b/src/serious_python_darwin/darwin/python_versions.properties @@ -1,8 +1,8 @@ # GENERATED by `dart run serious_python:gen_version_tables` from -# python-build manifest.json (release 20260701). Do not edit by hand. +# python-build manifest.json (release 20260708). Do not edit by hand. default_python_version=3.14 -dart_bridge_version=1.4.1 -python_build_release_date=20260701 +dart_bridge_version=1.5.0 +python_build_release_date=20260708 3.12.full_version=3.12.13 3.12.android_abis=arm64-v8a,x86_64,armeabi-v7a 3.13.full_version=3.13.14 diff --git a/src/serious_python_linux/CHANGELOG.md b/src/serious_python_linux/CHANGELOG.md index 89e73246..6e38240e 100644 --- a/src/serious_python_linux/CHANGELOG.md +++ b/src/serious_python_linux/CHANGELOG.md @@ -1,6 +1,6 @@ ## 4.3.0 -* Bump `dart_bridge` to **1.5.0**: multiprocessing child-interception exports (`serious_python_is_mp_invocation` / `serious_python_main`), consumed by the flet build template's `main.cc` via `dlopen("libdart_bridge.so")`. Relevant on Linux since Python 3.14 made `forkserver` (which execs `sys.executable`) the default start method. See the `serious_python` 4.3.0 notes. +* Bump `dart_bridge` to **1.5.0** (python-build snapshot `20260708`): multiprocessing child-interception exports (`serious_python_is_mp_invocation` / `serious_python_main`), consumed by the flet build template's `main.cc` via `dlopen("libdart_bridge.so")`. Relevant on Linux since Python 3.14 made `forkserver` (which execs `sys.executable`) the default start method. See the `serious_python` 4.3.0 notes. * `PYTHONINSPECT=1` is no longer set by any platform implementation. It had no effect on the embedded interpreter, but it leaked into the process environment where any *real* interpreter child (e.g. a serviced multiprocessing worker) would inherit it and hang in interactive mode after its command completed. ## 4.2.1 diff --git a/src/serious_python_linux/linux/python_versions.properties b/src/serious_python_linux/linux/python_versions.properties index faf98a2e..c0f41b51 100644 --- a/src/serious_python_linux/linux/python_versions.properties +++ b/src/serious_python_linux/linux/python_versions.properties @@ -1,8 +1,8 @@ # GENERATED by `dart run serious_python:gen_version_tables` from -# python-build manifest.json (release 20260701). Do not edit by hand. +# python-build manifest.json (release 20260708). Do not edit by hand. default_python_version=3.14 -dart_bridge_version=1.4.1 -python_build_release_date=20260701 +dart_bridge_version=1.5.0 +python_build_release_date=20260708 3.12.full_version=3.12.13 3.12.android_abis=arm64-v8a,x86_64,armeabi-v7a 3.13.full_version=3.13.14 diff --git a/src/serious_python_windows/CHANGELOG.md b/src/serious_python_windows/CHANGELOG.md index 5886f34e..de95b6bf 100644 --- a/src/serious_python_windows/CHANGELOG.md +++ b/src/serious_python_windows/CHANGELOG.md @@ -1,6 +1,6 @@ ## 4.3.0 -* Bump `dart_bridge` to **1.5.0**: multiprocessing child-interception exports, including the Windows wide-char variants `serious_python_is_mp_invocation_w` / `serious_python_main_w` (→ `Py_Main`) consumed by the flet build template's `wWinMain`. See the `serious_python` 4.3.0 notes. +* Bump `dart_bridge` to **1.5.0** (python-build snapshot `20260708`): multiprocessing child-interception exports, including the Windows wide-char variants `serious_python_is_mp_invocation_w` / `serious_python_main_w` (→ `Py_Main`) consumed by the flet build template's `wWinMain`. See the `serious_python` 4.3.0 notes. * `PYTHONINSPECT=1` is no longer set by any platform implementation. It had no effect on the embedded interpreter, but it leaked into the process environment where any *real* interpreter child (e.g. a serviced multiprocessing worker) would inherit it and hang in interactive mode after its command completed. ## 4.2.1 diff --git a/src/serious_python_windows/windows/python_versions.properties b/src/serious_python_windows/windows/python_versions.properties index faf98a2e..c0f41b51 100644 --- a/src/serious_python_windows/windows/python_versions.properties +++ b/src/serious_python_windows/windows/python_versions.properties @@ -1,8 +1,8 @@ # GENERATED by `dart run serious_python:gen_version_tables` from -# python-build manifest.json (release 20260701). Do not edit by hand. +# python-build manifest.json (release 20260708). Do not edit by hand. default_python_version=3.14 -dart_bridge_version=1.4.1 -python_build_release_date=20260701 +dart_bridge_version=1.5.0 +python_build_release_date=20260708 3.12.full_version=3.12.13 3.12.android_abis=arm64-v8a,x86_64,armeabi-v7a 3.13.full_version=3.13.14 From 58c29a6d36603875d45d3b2534d86a65d586a72c Mon Sep 17 00:00:00 2001 From: Feodor Fitsner Date: Wed, 8 Jul 2026 16:13:20 -0700 Subject: [PATCH 6/6] Remove generic version bump notes from platform CHANGELOGs Remove the generic 'Version bump aligning with the serious_python_* 4.3.0 release' line from the CHANGELOG entries across all platform implementations (Android, Darwin, Linux). The specific technical changes and dart_bridge updates are sufficient to document the release. --- src/serious_python_android/CHANGELOG.md | 1 - src/serious_python_darwin/CHANGELOG.md | 1 - src/serious_python_linux/CHANGELOG.md | 1 - 3 files changed, 3 deletions(-) diff --git a/src/serious_python_android/CHANGELOG.md b/src/serious_python_android/CHANGELOG.md index e1d0407c..c44e2a94 100644 --- a/src/serious_python_android/CHANGELOG.md +++ b/src/serious_python_android/CHANGELOG.md @@ -2,7 +2,6 @@ * `PYTHONINSPECT=1` is no longer set by any platform implementation. It had no effect on the embedded interpreter, but it leaked into the process environment where any *real* interpreter child (e.g. a serviced multiprocessing worker) would inherit it and hang in interactive mode after its command completed. No functional change on Android, which doesn't support process spawning. * Bump the bundled python-build snapshot to `20260708` (`dart_bridge` **1.5.0**). The new multiprocessing child-interception exports are present in the runtime but not wired up on Android, which doesn't support process spawning. -* Version bump aligning with the `serious_python_*` 4.3.0 release. ## 4.2.1 diff --git a/src/serious_python_darwin/CHANGELOG.md b/src/serious_python_darwin/CHANGELOG.md index aadc562c..8b2f210a 100644 --- a/src/serious_python_darwin/CHANGELOG.md +++ b/src/serious_python_darwin/CHANGELOG.md @@ -3,7 +3,6 @@ * Bump `dart_bridge` to **1.5.0** (python-build snapshot `20260708`): multiprocessing child-interception exports (`serious_python_is_mp_invocation` / `serious_python_main`), kept alive against the host link's `-dead_strip` both by `__attribute__((used))` in the archive and by keep-alive references in `SeriousPythonPlugin.swift`. See the `serious_python` 4.3.0 notes. * `prepare_macos.sh` / `prepare_ios.sh`: the extracted `dart_bridge.xcframework` in `dist_*` is now keyed to the dart_bridge version (`.dart_bridge_version` marker) — previously a version bump kept staging the stale extraction from the earlier version. * `PYTHONINSPECT=1` is no longer set by any platform implementation. It had no effect on the embedded interpreter, but it leaked into the process environment where any *real* interpreter child (e.g. a serviced multiprocessing worker) would inherit it and hang in interactive mode after its command completed. -* Version bump aligning with the `serious_python_*` 4.3.0 release. ## 4.2.1 diff --git a/src/serious_python_linux/CHANGELOG.md b/src/serious_python_linux/CHANGELOG.md index 27ea406b..6e38240e 100644 --- a/src/serious_python_linux/CHANGELOG.md +++ b/src/serious_python_linux/CHANGELOG.md @@ -2,7 +2,6 @@ * Bump `dart_bridge` to **1.5.0** (python-build snapshot `20260708`): multiprocessing child-interception exports (`serious_python_is_mp_invocation` / `serious_python_main`), consumed by the flet build template's `main.cc` via `dlopen("libdart_bridge.so")`. Relevant on Linux since Python 3.14 made `forkserver` (which execs `sys.executable`) the default start method. See the `serious_python` 4.3.0 notes. * `PYTHONINSPECT=1` is no longer set by any platform implementation. It had no effect on the embedded interpreter, but it leaked into the process environment where any *real* interpreter child (e.g. a serviced multiprocessing worker) would inherit it and hang in interactive mode after its command completed. -* Version bump aligning with the `serious_python_*` 4.3.0 release. ## 4.2.1