Skip to content

The asyncio REPL interactive daemon thread doesn't handle PYTHONSTARTUP exceptions #140287

@bswck

Description

@bswck

Bug report

Bug description:

That leads to flaky behaviors.

This is my PYTHONSTARTUP file:

raise ModuleNotFoundError("oops!")

ModuleNotFoundError is just an example exception that can occur in PYTHONSTARTUP scripts.

This is how the regular REPLs handle it (both the basic REPL and the new REPL):

❯ PYTHONSTARTUP=t.py ./python
Python 3.15.0a1+ (heads/main:fbf0843e39e, Oct 18 2025, 11:24:43) [GCC 15.2.1 20250808 (Red Hat 15.2.1-1)] on linux
Type "help", "copyright", "credits" or "license" for more information.
Traceback (most recent call last):
  File "t.py", line 1, in <module>
    raise ModuleNotFoundError("oops!")
ModuleNotFoundError: oops!
>>> 

The traceback is shown and we proceed to the loop.

For the asyncio REPL, startup file exception always causes it to exit immediately -- we'd never want the REPL to exit because of a startup file error. On top of that, it doesn't report the exception properly, because it's racing with the interpreter shutdown at that point.

I've found 3 variants of the incorrect behavior:

  1. The interactive daemon thread doesn't write the full traceback:

    ❯ PYTHONSTARTUP=t.py ./python -m asyncio
    asyncio REPL 3.15.0a1+ (heads/main:fbf0843e39e, Oct 18 2025, 11:24:43) [GCC 15.2.1 20250808 (Red Hat 15.2.1-1)] on linux
    Use "await" directly instead of "asyncio.run()".
    Type "help", "copyright", "credits" or "license" for more information.
    Exception in thread Interactive thread:
    exiting asyncio REPL...
    Traceback (most recent call last):
    
  2. The interactive daemon thread does flush, but after exiting is reported:

    ❯ PYTHONSTARTUP=t.py ./python -m asyncio
    asyncio REPL 3.15.0a1+ (heads/main:fbf0843e39e, Oct 18 2025, 11:24:43) [GCC 15.2.1 20250808 (Red Hat 15.2.1-1)] on linux
    Use "await" directly instead of "asyncio.run()".
    Type "help", "copyright", "credits" or "license" for more information.
    Exception in thread Interactive thread:
    exiting asyncio REPL...
    Traceback (most recent call last):
      File "/home/bswck/Python/cpython/Lib/threading.py", line 1075, in _bootstrap_inner
        self._context.run(self.run)
        ~~~~~~~~~~~~~~~~~^^^^^^^^^^
      File "/home/bswck/Python/cpython/Lib/asyncio/__main__.py", line 104, in run
        exec(startup_code, console.locals)
        ~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "t.py", line 1, in <module>
        raise ModuleNotFoundError("oops!")
    ModuleNotFoundError: oops!
    
  3. The interactive daemon tries to acquire stderr at interpreter shutdown, and fails:

    ❯ PYTHONSTARTUP=t.py ./python -m asyncio
    asyncio REPL 3.15.0a1+ (heads/main:fbf0843e39e, Oct 18 2025, 11:24:43) [GCC 15.2.1 20250808 (Red Hat 15.2.1-1)] on linux
    Use "await" directly instead of "asyncio.run()".
    Type "help", "copyright", "credits" or "license" for more information.
    Exception in thread Interactive thread:
    exiting asyncio REPL...
    Traceback (most recent call last):
      File "/home/bswck/Python/cpython/Lib/threading.py", line 1075, in _bootstrap_inner
        self._context.run(self.run)
        ~~~~~~~~~~~~~~~~~^^^^^^^^^^
    Fatal Python error: _enter_buffered_busy: could not acquire lock for <_io.BufferedWriter name='<stderr>'> at interpreter shutdown, possibly due to daemon threads
    Python runtime state: finalizing (tstate=0x00000000009c3818)
    
    Current thread 0x00007f6c4781cbc0 [python] (most recent call first):
      <no Python frame>
    Aborted (core dumped)
    

CPython versions tested on:

CPython main branch

Operating systems tested on:

Linux

Linked PRs

Metadata

Metadata

Assignees

No one assigned

    Labels

    stdlibStandard Library Python modules in the Lib/ directorytopic-asynciotopic-replRelated to the interactive shelltype-bugAn unexpected behavior, bug, or error

    Projects

    Status

    Todo

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions