-
-
Notifications
You must be signed in to change notification settings - Fork 30.5k
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
gh-66435: Allow nested event loops #93338
Conversation
Most changes to Python require a NEWS entry. Please add it using the blurb_it web app or the blurb command-line tool. |
Please update the title to A |
This is different from nest_asyncio right? This PR only allows 'nested event' loops, which I think is really great (I vaex we do this using this decorator https://github.com/vaexio/vaex/blob/633970528cb5091ef376dbca2e4721cd42525419/packages/vaex-core/vaex/asyncio.py#L7 but it's using the 'nest_asyncio' will also run the tasks of the parent/previous event loop, i.e. it will give an output like this:
Which basically leads to a I think with this PR it is not possible to resume a task from the previous event_loop, is that right? To make it more concrete, this example works with import asyncio
+import nest_asyncio
+
+nest_asyncio.apply()
+
+t = None
+
async def task(name):
for i in range(10):
@@ -8,6 +14,7 @@
async def bar():
+ await t
asyncio.create_task(task("bar"))
await asyncio.sleep(1.1)
print("bar done")
@@ -20,6 +27,7 @@
async def main():
+ global t
t = asyncio.create_task(task("main")) # not executed until foo() is done
foo()
await asyncio.sleep(1.1) # t resumes execution output:
Does this PR give an exception, does it run it, or does it deadlock? I think the appropriate behavior should be an exception (complaining the awaited task |
Misc/NEWS.d/next/Library/2022-05-30-09-25-24.gh-issue-66435.E4YBFo.rst
Outdated
Show resolved
Hide resolved
@maartenbreddels indeed, I didn't copy exactly the code from |
If we don't, then it is not cooperative multitasking anymore. But I can't find in the Python docs that asyncio claims it is actually. In any case, it will probably break existing code. |
I think it would be less dangerous, as you mentioned, that
Yes, that's why we would need to opt-in for this behavior. |
@davidbrochart would it be possible for jupyter_client to spawn a python subprocess for running user code in instead? |
A Jupyter kernel already runs in its own process, and jupyter-client communicates with it through ZMQ sockets. |
da55551
to
d542989
Compare
I've simplified the changes to what I think is the minimum to get the behavior described in the top comment. Now the nested call to asyncio.run(bar(), running_ok=True) |
d542989
to
3b5df83
Compare
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.
@davidbrochart @maartenbreddels If you have time to update this PR, we can discuss it at JupyterCon.
3b5df83
to
0b54e74
Compare
Thanks for the heads up @willingc, I rebased on import asyncio
async def task(name):
for i in range(10):
await asyncio.sleep(0.1)
print(f"from {name}: {i}")
async def bar():
asyncio.create_task(task("bar"))
await asyncio.sleep(1.1)
print("bar done")
def foo():
# asyncio.run inside an already running event loop
# pre-empts the execution of any other task in the event loop
asyncio.run(bar(), running_ok=True)
async def main():
t = asyncio.create_task(task("main")) # not executed until foo() is done
foo()
await asyncio.sleep(1.1) # t resumes execution
asyncio.run(main()) That will print:
If we wanted the nested call to
We would not really need this PR, we would just check if a loop is already running, and if yes then call |
@davidbrochart Could you sign the CLA, please? #93338 (comment) |
Done. |
0b54e74
to
fd22cad
Compare
Whoa. A process issue: discussions about whether a particular feature should be accepted should happen on an Issue, not in a PR. The best thing to do is to reopen gh-66435, which I will do. See you there! (I do appreciate the discussion and the clear examples of two different proposed behaviors.) |
@davidbrochart I'm closing this PR since we decided to not add nested asyncio to the library. #66435 (comment) Thanks for your effort here and your suggestion on the issue for a third party library. |
This PR is basically a copy/paste of @erdewit's nest_asyncio library. It allows the event loop to be re-entrant, by making it possible to call
asyncio.run()
inside an already running event loop.This feature request was rejected in the past, but @1st1 recently mentioned that he could reconsider this decision.
Here is an example:
This will print: