-
-
Notifications
You must be signed in to change notification settings - Fork 30.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
bpo-37028: Implement asyncio REPL (activated via 'python -m asyncio') #13472
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I test it (debian 9) and this is great!
Looks good, works fine! I think unittests are needed. |
You should be able to keep the same eventloop running right ? |
Lib/asyncio/__main__.py
Outdated
|
||
|
||
if __name__ == '__main__': | ||
console = AsyncIOInteractiveConsole(locals()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is the locals()
here on purpose ? Seem to leak some values...
$ python -m asyncio
asyncio REPL
Python 3.8.0a4+ (heads/arepl-dirty:0efd6fb39b, May 20 2019, 19:17:43)
[Clang 9.0.0 (clang-900.0.39.2)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> code
<module 'code' from '/Users/bussonniermatthias/dev/cpython/Lib/code.py'>
>>> inspect
<module 'inspect' from '/Users/bussonniermatthias/dev/cpython/Lib/inspect.py'>
>>> sys
<module 'sys' (built-in)>
>>> console
<__main__.AsyncIOInteractiveConsole object at 0x109ab5be0>
>>> banner
'asyncio REPL\n\nPython 3.8.0a4+ (heads/arepl-dirty:0efd6fb39b, May 20 2019, 19:17:43) \n[Clang 9.0.0 (clang-900.0.39.2)] on darwin\nType "help", "copyright", "credits" or "license" for more information.\n'
>>>
And to extend on my comment, here is what I am suggesting as a behavior (but maybe we do that after beta1), where the background coroutines run when there are foreground ones:
The drawback would be :
|
As a guideline here is one of the bug report we got when implementing this on IPython, it will give you an idea of the kind of stuff people will try in async-repl. |
Ah, this is quite interesting. The loop is indeed not running in the background which might confuse some users. @asvetlov Andrew what do you think? Should we run asyncio event loop in the main thread, and implement the REPL in another non-main thread? |
No, REPL in non-main thread is a bad idea. |
Yeah, I think pausing the event loop while waiting for input is going to give a frustrating experience. Also consider: >>> async def ticker():
... while True:
... await asyncio.sleep(1)
... print("tick!")
>>> asyncio.create_task(ticker)
>>> (Or more realistically, something like starting a server in a background task from the REPL.) You could put the RPL parts in another thread and the E in the main thread, but then exiting may be tricky and control-C may act pretty wonky. You could put RPL in the main thread and E in another thread, not sure if that would help or not... |
Oh hah, sorry I skimmed the thread and missed that @Carreau used that exact example already :-) |
And the other general approach would be to write the whole REPL async, but that requires support for async stdio, which is complicated (see also). |
REPL not in main thread is bad from experience. Many library expect to be in main. There are two things in play here:
Or blocking the loop when requesting input:
I believe they have similar– but not quite identical behavior. There is also the possibility "let's not put that in 3.8"; it's small enough that it could be it's own package to iterate on – and well, it works already with IPython :-P |
Agree. I was super confused why @Carreau's examples with
I assume you meant "event loop in non-main thread is a bad idea"?
Why? What libraries have to do with this?
I'm OK to iterate. If there are open issues we won't push this in 3.8. However if there's no actual iteration on design, I prefer to push things and let people use them. asyncio REPL isn't critical or dependable piece of software, we can fix/tweak it. As for IPython -- I'm glad that it exists, but I still can't get accustomed to it and always want a quick built-in asyncio repl to test things. @ALL: I've pushed an updated implementation that runs the REPL in a separate thread, keeping an asyncio event loop always running in the main thread. Seems to work just fine, please try it out. |
Some feedback:
Traceback for keyboard interrupt is confusing a little.
The same question. Maybe REPL can hide it's own part of stack traceback? The worst part:
I've started a task for First, dots printed by the task are mixed with my typing. It makes editing REPL string almost impossible. Also, pressing Ctrl+C when editing does nothing. In general, not bad at all if mentioned inconveniences can be fixed. |
The problem was mentioned by @Carreau |
Thanks for trying it out :)
Both ^C outputs can be fixed.
This is tricky. I guess the only answer I have to this is "don't print in background tasks". The exact behaviour you see is easy to replicate in the standard Python repl just by spawning a background thread that prints. Since this is OK for the standard repl, I assume we can dismiss this usability annoyance for the asyncio one. |
Yeah. I think we should document it, because allowing both |
Agree.
Agree again. |
Please take a look on the last line. It is printed after the REPL exit. |
What's wrong with it? The coroutine wasn't actually awaited. I don't think that silencing this warning in the REPL is a good idea. Here's an example interaction where having this warning will hint to the user that they should probably add an "await":
One other possibility is to filter this warning out while the REPL is exiting... |
I mean it is printed after |
I love that debug mode just works!
|
This makes it easy to play with asyncio APIs with simply using async/await in the REPL.
@asvetlov The latest update should address your comments. |
from a top of my head i've seem people using open-cv which seemed to not like bing imported in not-main-thread. I'll see if I can your new version to crash :-)
Well, it is kinda-half-possible; IPython does it; if there are no asyncio task running, and no top-level await we just use a dumb-coroutine iterator. But that's a detail; I agree it's overkill to try-to get both to work. |
@Carreau seems like you fall into the same trap as me. @njsmith mentioned this way:
Looks like "wonky" approach works pretty well. |
pasting multiple lines misprints the
|
Nevermind, this is my system that have an issue with readline. |
@asvetlov Please feel free to review this. If you green light it I'll merge and add tests later. |
@@ -0,0 +1 @@ | |||
Implement asyncio REPL |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can a note be added to Whats New too?
Much better but the behavior of |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Anyway, looks good to me
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks good !
We likely can also have entries in tutorials, and |
…-13472) This makes it easy to play with asyncio APIs with simply using async/await in the REPL.
This makes it easy to play with asyncio APIs with simply
using async/await in the REPL.
@asvetlov would you mind playing with this? Pull the branch, make sure to rebuild Python, and then
./python -m asyncio
. I quite like this and I think it would be a valuable addition to asyncio 3.8.https://bugs.python.org/issue37028