Skip to content

python -m asyncio does not respect PYTHON_BASIC_REPL=1 #140002

Description

@provinzkraut

Bug report

Bug description:

When using python -m asyncio, the REPL does not respect PYTHON_BASIC_REPL=1.

Using a test case from the pyrepl test suite, we can clearly see pyrepl is being used:

# The site module must not load _pyrepl if PYTHON_BASIC_REPL is set
commands = ("import sys\n"
"print('_pyrepl' in sys.modules)\n"
"exit()\n")
env["PYTHON_BASIC_REPL"] = "1"

PYTHON_BASIC_REPL=1 python -m asyncio 
asyncio REPL 3.15.0a0 (heads/main:81959a0364, Oct 12 2025, 12:47:58) [GCC 13.3.0] on linux
Use "await" directly instead of "asyncio.run()".
Type "help", "copyright", "credits" or "license" for more information.
>>> import asyncio
>>> import sys
>>> '_pyrepl' in sys.modules
True

Looking at the source of asyncio.__main__, this makes perfect sense, as the asyncio REPL is a customised version of _pyrepl.console.InteractiveColoredConsole:

from _pyrepl.console import InteractiveColoredConsole
from . import futures
class AsyncIOInteractiveConsole(InteractiveColoredConsole):

CPython versions tested on:

CPython main branch

Operating systems tested on:

Linux

Activity

  1. picnixz commented on Oct 12, 2025

    @picnixz
    Member
  2. provinzkraut commented on Oct 12, 2025

    @provinzkraut
    ContributorAuthor

    The fix here would probably have to consist of having 2 separate asyncio REPL implementations, since InteractiveColoredConsole already inherits from code.InteracticeConsole, and over time, a few pyrepl-specific changes have been introduced to AsyncIOInteractiveConsole.

    Sounds like a split would add a bit of maintenance burden for the future. Maybe it could also be considered to explicitly only support pyrepl with asyncio -m?

    Would probably still have to fix this for the current version, as it's not really working "as advertised".

  3. StanFromIreland commented on Oct 12, 2025

    @StanFromIreland
    Member

    Would probably still have to fix this for the current version, as it's not really working "as advertised".

    Is it though? The asyncio repl docs (a few sections down, direct linking is not possible) do not mention it respecting PYTHON_BASIC_REPL?

  4. provinzkraut commented on Oct 12, 2025

    @provinzkraut
    ContributorAuthor

    Would probably still have to fix this for the current version, as it's not really working "as advertised".

    Is it though? The asyncio repl docs (a few sections down, direct linking is not possible) do not mention it respecting PYTHON_BASIC_REPL?

    Well it was deliberately introduced in #119433, which also includes in its description:

    support PYTHON_BASIC_REPL

    so whether documented or not, it was definitely intended to work, and it does do something, it just doesn't properly fall back to the regular REPL.

  5. johnslavik commented on Oct 12, 2025

    @johnslavik
    Member

    I don't think there is any problem with how PYTHON_BASIC_REPL environment variable is handled, but there are problems regarding the code paths that asyncio REPL hits. The current asyncio REPL does hit code paths of something that is reserved for the new REPL only.

    Namely, it does not handle multi-line input properly, because it runs runsource() of InteractiveColoredConsole.runsource() which was only meant to be called from _pyrepl.simple_interact.run_multiline_interactive_console that handles multi-line input using its own logic (tracked in #140013).

    Other than that, is there anything else that manifests improper fallback?
    What are the exact behaviors that don't align with what you are expecting?

    (Of course ignoring all differences stemming from not calling sys._baserepl(), because the asyncio REPL has to intercept inputs and produce coroutine functions from them on the fly using a Python wrapper, at least as long the basic REPL fallback is implemented in Python).

  6. johnslavik commented on Oct 12, 2025

    @johnslavik
    Member

    Other than that, is there anything else that manifests improper fallback?
    What are the exact behaviors that don't align with what you are expecting?

    Please describe some specifics so we can set up issues to track. I'm filing the one for multi-line input handling.

  7. provinzkraut commented on Oct 18, 2025

    @provinzkraut
    ContributorAuthor

    I don't think there is any problem with how PYTHON_BASIC_REPL environment variable is handled, but there are problems regarding the code paths that asyncio REPL hits. The current asyncio REPL does hit code paths of something that is reserved for the new REPL only.

    Just to be clear: You are saying that it is not generally a problem that setting PYTHON_BASIC_REPL=1 does not use the basic repl?

    If so, that is at least somewhat unexpected, and, judging from the tests and code, it does not appear to be the intended behaviour.
    For example, looking at _pyrepl.main.interactive_console:

    def interactive_console(mainmodule=None, quiet=False, pythonstartup=False):
    if not CAN_USE_PYREPL:
    if not os.getenv('PYTHON_BASIC_REPL') and FAIL_REASON:
    from .trace import trace
    trace(FAIL_REASON)
    print(FAIL_REASON, file=sys.stderr)
    return sys._baserepl()

    we can see that it falls back to sys._baserepl, and not into a "baserepl-like mode of pyrepl".

    If this discrepancy in behaviour is considered to not be an issue though that's fine with me, as I do not know the intentions behind this divergence and there doesn't seem to be anything obviously wrong with the behaviour.

    What are the exact behaviors that don't align with what you are expecting?

    I haven't observed any discrepancies, other than a test case failing unsuspectedly when working on the asyncio repl. I tried to adapt this one for an asyncio repl test and found that it fails due to the behaviour mentioned above.

  8. johnslavik commented on Oct 18, 2025

    @johnslavik
    Member

    Are there any user-facing issues with the asyncio REPL when PYTHON_BASIC_REPL=1 is set?

    That test assertion is violated by python -m asyncio because the asyncio REPL must import _pyrepl to build its own compile-and-run loop that supports top-level await. Consequently, because it supports top-level awaits, it can't fall back to sys._baserepl (sys._baserepl doesn't implement an "asyncio mode"). The failure is therefore expected and has no user-visible consequence -- it's not a bug in the asyncio REPL.

  9. provinzkraut commented on Oct 18, 2025

    @provinzkraut
    ContributorAuthor

    Are there any user-facing issues with the asyncio REPL when PYTHON_BASIC_REPL=1 is set?

    As I explained in my comment above, none that I am aware of, other than the fact that it's unexpected behaviour.

    That test assertion is violated by python -m asyncio because the asyncio REPL must import _pyrepl to build its own compile-and-run loop that supports top-level await. Consequently, because it supports top-level awaits, it can't fall back to sys._baserepl (sys._baserepl doesn't implement an "asyncio mode")

    I'm not sure I understand the part about the asyncio REPL depending on _pyrepl. Maybe I'm missing something here?

    The asyncio REPL was introduced before _pyrepl. Before #119433 it did not use _pyrepl, and from my understanding, there's nothing the asyncio REPL does that inherently requires functionality exclusively available via _pyrepl.

    Can you explain what functionality of _pyrepl (specifically InteractiveColoredConsole) the asyncio REPL needs to support top-level await, that is not provided by code.InteractiveConsole, which it used before the introduction of _pyrepl?

  10. pablogsal commented on Oct 23, 2025

    @pablogsal
    Member
  11. johnslavik commented on Oct 24, 2025

    @johnslavik
    Member

    Filed #140570 where we explicitly recommend using the new REPL mode instead.

  12. moved this from Todo to Done in asyncioon Jul 24, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

stdlibStandard Library Python modules in the Lib/ directorytopic-asynciotype-bugAn unexpected behavior, bug, or error

Projects

  • Status
    Done

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions