Skip to content

Fix native mode crash on Linux Python 3.14 (forkserver default) - #156

Open
evnchn wants to merge 1 commit into
mainfrom
fix/native-mp-forkserver-py314
Open

Fix native mode crash on Linux Python 3.14 (forkserver default)#156
evnchn wants to merge 1 commit into
mainfrom
fix/native-mp-forkserver-py314

Conversation

@evnchn

@evnchn evnchn commented May 20, 2026

Copy link
Copy Markdown
Owner

Spike for upstream issue zauberzeug/nicegui#6062. Completes the spawn-context migration started in #6045, which moved Queue/Pipe/Event to SPAWN_CONTEXT but left mp.Process on the default context.

Python 3.14 changed the Linux multiprocessing default from fork to forkserver. Forkserver re-imports the user's main module to bootstrap workers but does not use the --multiprocessing-fork argv trampoline, so mp.freeze_support() cannot short-circuit and _check_not_importing_main() raises:

RuntimeError: An attempt has been made to start a new process before
the current process has finished its bootstrapping phase.

Fix: one-line change to native.SPAWN_CONTEXT.Process(...). Spawn's trampoline runs the target and exits before reaching ui.run() in the child, so app.native.window_args / start_args / settings set in the user script still propagate correctly (verified empirically on Linux 3.14.5 and macOS 3.14.4).

Fixes zauberzeug#6062.

zauberzeug#6045 migrated the native-mode IPC primitives (Queue, Pipe, Event) to
SPAWN_CONTEXT but left the Process on the default context. Python 3.14
changed the Linux default start method from 'fork' to 'forkserver',
which re-imports the user's main module to bootstrap workers but does
NOT use the '--multiprocessing-fork' argv trampoline that lets
mp.freeze_support() short-circuit, so the doc example crashes with:

    RuntimeError: An attempt has been made to start a new process before
    the current process has finished its bootstrapping phase.

Switching the Process to SPAWN_CONTEXT keeps every native-mode IPC
primitive on the same context and works on all supported Pythons:
spawn's trampoline runs the target and exits the child before reaching
ui.run() on re-import, so app.native.window_args / start_args /
settings set in the user script still propagate correctly.
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