diff --git a/Lib/asyncio/__main__.py b/Lib/asyncio/__main__.py index 10bfca3cf96b3e..f15b559c29a921 100644 --- a/Lib/asyncio/__main__.py +++ b/Lib/asyncio/__main__.py @@ -11,6 +11,7 @@ import threading import types import warnings +from code import InteractiveConsole from _colorize import get_theme from _pyrepl.console import InteractiveColoredConsole @@ -27,6 +28,11 @@ def __init__(self, locals, loop): self.loop = loop self.context = contextvars.copy_context() + def runsource(self, source, filename="", symbol="single"): + if CAN_USE_PYREPL: + return super().runsource(source, filename, symbol) + return InteractiveConsole.runsource(self, source, filename, symbol) + def runcode(self, code): global return_code future = concurrent.futures.Future() diff --git a/Lib/test/test_repl.py b/Lib/test/test_repl.py index 54e69277282c30..085283179bb11a 100644 --- a/Lib/test/test_repl.py +++ b/Lib/test/test_repl.py @@ -357,6 +357,18 @@ def f(): class TestAsyncioREPL(unittest.TestCase): + def test_multiline_support(self): + user_input = dedent("""\ + async def spam(): + print("eggs" + "ham") + + await spam() + """) + p = spawn_repl("-m", "asyncio") + p.stdin.write(user_input) + output = kill_python(p) + self.assertIn("eggsham", output) + def test_multiple_statements_fail_early(self): user_input = "1 / 0; print(f'afterwards: {1+1}')" p = spawn_repl("-m", "asyncio") @@ -389,7 +401,7 @@ def test_toplevel_contextvars_async(self): """) p = spawn_repl("-m", "asyncio") p.stdin.write(user_input) - user_input2 = "async def set_var(): var.set('ok')\n" + user_input2 = "async def set_var(): var.set('ok')\n\n" p.stdin.write(user_input2) user_input3 = "await set_var()\n" p.stdin.write(user_input3) diff --git a/Misc/NEWS.d/next/Library/2025-10-13-01-59-57.gh-issue-140013.CJc3vA.rst b/Misc/NEWS.d/next/Library/2025-10-13-01-59-57.gh-issue-140013.CJc3vA.rst new file mode 100644 index 00000000000000..fb63a513d7e9fb --- /dev/null +++ b/Misc/NEWS.d/next/Library/2025-10-13-01-59-57.gh-issue-140013.CJc3vA.rst @@ -0,0 +1,2 @@ +The :mod:`asyncio` REPL in basic mode now supports multi-line inputs. Contributed +by Bartosz Sławecki.