<div dir="ltr">Yury this looks great! Thanks for suggesting this.<br><br>One of the big problems I've seen with the basic approachability of async/await in Python is the lack of interpreter support. Now this makes that a lot easier by having a one function you can use makes this a lot easier (One of the main things I use `curio` for is simply being able to `curio.run` an Awaitable in the interpreter without having to go through the normal asyncio dance). I would love to see if we could extend this even further to making `await` "Just Work" in the interpreter.<div><br></div><div>Thanks,</div><div>Roy</div><div><br><div class="gmail_extra"><br><div class="gmail_quote">On Wed, Nov 16, 2016 at 12:53 PM, Yury Selivanov <span dir="ltr"><<a href="mailto:yselivanov@gmail.com" target="_blank">yselivanov@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span class=""><br>
> On Nov 16, 2016, at 3:35 PM, Nathaniel Smith <<a href="mailto:njs@pobox.com">njs@pobox.com</a>> wrote:<br>
><br>
> What's the use case for the async generator version? Could the yield be replaced by 'await loop.shutting_down()’?<br>
<br>
</span>Async generator version (inspired by contextlib.contextmanager decorator) is needed in cases where you want loop.run_forever.<br>
<br>
The PR originally proposed to add `asyncio.forever()` (which is the same idea as `loop.shutting_down()`), but nobody particularly liked it.<br>
<br>
A couple of thoughts/reasons:<br>
<br>
1. Some pretty intrusive modifications are required to be made in the event loop to make it work. That means all other event loops (including uvloop) will have to be modified to support it. This is the most important reason.<br>
<br>
2. `loop.shutting_down()` is a no go because it’s a method on the loop object. We can discuss `asyncio.shutting_down`. The whole point of this discussion is to get rid of the event loop.<br>
<br>
3. `await forever()` and `await shutting_down()` have a naming issue - both look weird:<br>
<br>
async def main():<br>
srv = await asyncio.start_server(…)<br>
try:<br>
await asyncio.shutting_down() # or await forever()<br>
finally:<br>
srv.close()<br>
await srv.wait_closed()<br>
<br>
In the above example, what does the second ‘await’ do? Will it be resolved when the loop is stopped with ‘loop.stop()’? Or when a KeyboardInterrupt occurs? What will happen if you await on it in parallel from 10 different coroutines? It’s just difficult to define a clear semantics of this coroutine.<br>
<br>
Using an asynchronous generator for this case is easier in terms of implementation and in terms of specifying the execution semantics. And the approach of using generators for such things isn’t new - we have contextlib.contextmanager decorator which is quite popular.<br>
<div class="HOEnZb"><div class="h5"><br>
Yury<br>
______________________________<wbr>_________________<br>
Async-sig mailing list<br>
<a href="mailto:Async-sig@python.org">Async-sig@python.org</a><br>
<a href="https://mail.python.org/mailman/listinfo/async-sig" rel="noreferrer" target="_blank">https://mail.python.org/<wbr>mailman/listinfo/async-sig</a><br>
Code of Conduct: <a href="https://www.python.org/psf/codeofconduct/" rel="noreferrer" target="_blank">https://www.python.org/psf/<wbr>codeofconduct/</a></div></div></blockquote></div><br></div></div></div>