Skip to content

Interpreter Methods For Main Interpreter Fail Unexpectedly #139458

Open

Description

@ericsnowcurrently

Bug report

Bug description:

The following should run without error:

import contextlib
from concurrent import interpreters

assert __name__ == '__main__'

DIV1 = 'v' * 40
DIV2 = '^' * 40

@contextlib.contextmanager
def dump_traceback():
    try:
        yield
    except Exception:
        import traceback
        print()
        print(DIV1)
        traceback.print_exc()
        print(DIV2)

# First try with the current interpreter.
interp0 = interpreters.get_current()
assert interp0 is interpreters.get_main()

# Interpreters "running main" cannot exec or call.
assert interp0.is_running
with dump_traceback():
    try:
        interp0.exec('None')
    except interpreters.InterpreterError as exc:
        if 'running main' not in str(exc):
            raise
with dump_traceback():
    try:
        interp0.call(print, 'spam!', flush=True)
    except interpreters.InterpreterError as exc:
        if 'running main' not in str(exc):
            raise

# prepare_main() should still work
assert 'spam' not in globals()
with dump_traceback():
    interp0.prepare_main(spam=11)
    assert spam == 11

# Try with a subinterpreter
interp1 = interpreters.create()

assert 'q' not in globals()
with dump_traceback():
    interp1.exec("""if True:
        from concurrent import interpreters
        q = interpreters.create_queue()
        interp0 = interpreters.get_main()
        interp0.prepare_main(q=q)
        q.put_nowait(42)
        """)
    assert 'q' in globals()
    val = q.pop()
    assert val == 42

Instead, the four different calls against interp0 raise InterpreterError with "cannot ... unrecognized interpreter 0". The calls to exec() and call() should fail with something like "running main". The call to prepare_main() should work. Whether prepare_main() should work or not is a separate matter. Regardless, the main interpreter should be recognized.

Note that interp0.is_running does work, as expected.

CPython versions tested on:

3.15, 3.14

Operating systems tested on:

No response

Linked PRs

Activity

  1. added
    type-bugAn unexpected behavior, bug, or error
    stdlibStandard Library Python modules in the Lib/ directory
    3.14bugs and security fixes
    3.15bugs and security fixes
    on Sep 30, 2025
  2. ericsnowcurrently commented on Sep 30, 2025

    @ericsnowcurrently
    MemberAuthor

    prepare_main(), exec(), and call() all pass restrict=True to the corresponding low-level functions, while is_running() uses the default (False). That's the key difference here. The question is why resolve_interp() in _interpretersmodule.c makes "restrict=True" for the main interpreter mean "not recognized".

  3. ericsnowcurrently commented on Oct 2, 2025

    @ericsnowcurrently
    MemberAuthor

    FWIW, there is a separate question of if other interpreters not created through the interpreters module should be recognized. At the least the error message from the 3 methods should be more helpful than "cannot ... unrecognized interpreter X". Perhaps something more like "not managed by interpreters module".

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

3.14bugs and security fixes3.15bugs and security fixesstdlibStandard Library Python modules in the Lib/ directorytopic-subinterpreterstype-bugAn unexpected behavior, bug, or error

Projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions