Skip to content

fix(runtime): don't shadow builtin print unless mo.Thread is used (#9765)#9766

Merged
mscolnick merged 1 commit into
mainfrom
ms/krakow-v1
Jun 2, 2026
Merged

fix(runtime): don't shadow builtin print unless mo.Thread is used (#9765)#9766
mscolnick merged 1 commit into
mainfrom
ms/krakow-v1

Conversation

@mscolnick
Copy link
Copy Markdown
Contributor

@mscolnick mscolnick commented Jun 2, 2026

marimo unconditionally replaced the builtin print in every cell's
global namespace with print_override (used to route mo.Thread output
to the right cell). This broke libraries that special-case the genuine
builtin, e.g. numba's @njit, which requires print is builtins.print
and otherwise fails with "Untyped global name 'print': Cannot determine
Numba type of <class 'function'>".

Only patch print when the feature that needs it is actually used:
stop installing the override in create_main_module, and instead have
mo.Thread install it lazily into the kernel globals on construction.
Thread-free notebooks now keep the real builtin print, so numba and
similar libraries work again.

Removes the now-unused print_override plumbing through KernelArgs and
create_main_module/patch_main_module.

Fixes #9765

)

marimo unconditionally replaced the builtin `print` in every cell's
global namespace with `print_override` (used to route mo.Thread output
to the right cell). This broke libraries that special-case the genuine
builtin, e.g. numba's `@njit`, which requires `print is builtins.print`
and otherwise fails with "Untyped global name 'print': Cannot determine
Numba type of <class 'function'>".

Only patch `print` when the feature that needs it is actually used:
stop installing the override in create_main_module, and instead have
mo.Thread install it lazily into the kernel globals on construction.
Thread-free notebooks now keep the real builtin print, so numba and
similar libraries work again.

Removes the now-unused print_override plumbing through KernelArgs and
create_main_module/patch_main_module.
Copilot AI review requested due to automatic review settings June 2, 2026 21:30
@vercel
Copy link
Copy Markdown

vercel Bot commented Jun 2, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
marimo-docs Ready Ready Preview, Comment Jun 2, 2026 9:31pm

Request Review

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes a runtime compatibility issue where marimo shadowed the builtin print in every cell, breaking libraries (notably numba) that require print is builtins.print. The override is now applied only when mo.Thread is actually used, preserving the real builtin in thread-free notebooks while keeping thread output routing functional.

Changes:

  • Stop installing print_override in create_main_module / kernel startup so thread-free notebooks keep the builtin print.
  • Lazily patch print into kernel globals when a mo.Thread is constructed.
  • Remove the now-unused print_override plumbing from KernelArgs and associated kernel/session creation call sites; add tests covering both behaviors.

Reviewed changes

Copilot reviewed 10 out of 10 changed files in this pull request and generated no comments.

Show a summary per file
File Description
tests/_runtime/test_threads.py Adds coverage ensuring print remains builtin without threads, and becomes overridden after constructing mo.Thread.
tests/_runtime/_helpers/session.py Updates test kernel session construction to match the simplified KernelArgs (removes print_override_fn).
marimo/_runtime/threads.py Implements lazy print patching in mo.Thread.__init__ for kernel contexts.
marimo/_runtime/runtime.py Removes unconditional print_override import and kernel arg wiring.
marimo/_runtime/patches.py Removes print_override from create_main_module/patch_main_module and documents the new lazy behavior.
marimo/_runtime/kernel_lifecycle.py Removes print_override_fn from KernelArgs and stops passing it into module patching.
marimo/_runtime/context/script_context.py Updates create_main_module call signature after removing print_override parameter.
marimo/_runtime/app/script_runner.py Updates create_main_module calls to new signature.
marimo/_runtime/app/kernel_runner.py Updates create_main_module call to new signature.
marimo/_pyodide/pyodide_session.py Updates KernelArgs construction after removing print_override_fn.

Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No issues found across 10 files

Architecture diagram
sequenceDiagram
    participant Cell as User Cell
    participant Module as Kernel __main__ Module
    participant Thread as mo.Thread
    participant PrintOverride as print_override()
    participant Kernel as Kernel
    
    Note over Cell,Kernel: Normal cell execution (no mo.Thread)
    Cell->>Module: Execute cell code
    Cell->>Cell: print("hello") resolves to builtins.print
    Note right of Cell: Libraries like numba see print is builtins.print
    
    alt mo.Thread is constructed
        Cell->>Thread: mo.Thread(target=lambda: ...)
        Thread->>Kernel: constructor called
        Note over Thread,Kernel: Lazy patching of print
        Thread->>PrintOverride: ctx.globals.setdefault("print", print_override)
        PrintOverride-->>Module: Patches print in kernel globals
        Kernel-->>Thread: ThreadLifecycle registered
    end
    
    Note over Cell,Kernel: Thread output routing (when thread exists)
    Cell->>Thread: thread.start()
    Thread->>Thread: target() executes
    Thread->>PrintOverride: print() calls print_override
    PrintOverride-->>Kernel: Routes output to spawning cell's stream
    Kernel-->>Cell: Output appears in cell
    
    Note over Cell,Kernel: Thread-free notebooks keep real builtin
    alt No mo.Thread created
        Cell->>Module: print refers to builtins.print
        Cell->>Cell: print is builtins.print → True
        Note right of Cell: numba @njit works correctly
    end
    
    Note over Cell,Module: Boundary: cell globals vs kernel globals
    Module->>Kernel: print lives in kernel __main__ module globals
    Kernel->>PrintOverride: Only set if Thread exists
Loading

Re-trigger cubic

Copy link
Copy Markdown
Contributor

@akshayka akshayka left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TIL. Thank you

@mscolnick mscolnick merged commit e55e7ba into main Jun 2, 2026
47 of 48 checks passed
@mscolnick mscolnick deleted the ms/krakow-v1 branch June 2, 2026 22:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Marimo replaces builtin print, breaking Numba @njit compilation

3 participants