[Async-sig] Adding asyncio.run() function in Python 3.6

Yury Selivanov yselivanov at gmail.com
Wed Nov 16 15:53:50 EST 2016


> On Nov 16, 2016, at 3:35 PM, Nathaniel Smith <njs at pobox.com> wrote:
> 
> What's the use case for the async generator version? Could the yield be replaced by 'await loop.shutting_down()’?

Async generator version (inspired by contextlib.contextmanager decorator) is needed in cases where you want loop.run_forever.

The PR originally proposed to add `asyncio.forever()` (which is the same idea as `loop.shutting_down()`), but nobody particularly liked it.

A couple of thoughts/reasons:

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.

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.

3. `await forever()` and `await shutting_down()` have a naming issue - both look weird:

  async def main():
    srv = await asyncio.start_server(…)
    try:
       await asyncio.shutting_down()  # or await forever()
    finally:
       srv.close()
       await srv.wait_closed()

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.

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.

Yury


More information about the Async-sig mailing list