[Python-Dev] PEP 525

Yury Selivanov yselivanov.ml at gmail.com
Wed Aug 24 15:00:19 EDT 2016


On 2016-08-24 12:35 PM, Guido van Rossum wrote:

> On Wed, Aug 24, 2016 at 8:17 AM, Yury Selivanov 
> <yselivanov.ml at gmail.com <mailto:yselivanov.ml at gmail.com>> wrote:
>
>     On 2016-08-23 10:38 PM, Rajiv Kumar wrote:
>
>         I was playing with your implementation to gain a better
>         understanding of the operation of asend() and friends. Since I
>         was explicitly trying to "manually" advance the generators, I
>         wasn't using asyncio or other event loop. This meant that the
>         first thing I ran into with my toy code was the RuntimeError
>         ("cannot iterate async generator without finalizer set").
>
>         As you have argued elsewhere, in practice the finalizer is
>         likely to be set by the event loop. Since the authors of event
>         loops are likely to know that they should set the finalizer,
>         would it perhaps be acceptable to merely issue a warning
>         instead of an error if the finalizer is not set? That way
>         there isn't an extra hoop to jump through for simple examples.
>
>         In my case, I just called
>             sys.set_asyncgen_finalizer(lambda g: 1)
>         to get around the error and continue playing :) (I realize
>         that's a bad thing to do but it didn't matter for the toy cases)
>
>
>     Yeah, maybe warning would be sufficient.  I just find it's highly
>     unlikely that a lot of people would use async generators without a
>     loop/coroutine runner, as it's a very tedious process.
>
>
> Heh, I had the same reaction as Rajiv. I think the tediousness is 
> actually a good argument that there's no reason to forbid this. I 
> don't even think a warning is needed. People who don't use a coroutine 
> runner are probably just playing around (maybe even in the REPL) and 
> they shouldn't get advice unasked.

Good point.

>
> Would it be possible to print a warning only when an async generator 
> is being finalized and doesn't run straight to the end without 
> suspending or yielding? For regular generators we have a similar 
> exception (although I don't recall whether we actually warn) -- if you 
> call close() and it tries to yield another value it is just GC'ed 
> without giving the frame more control.

Yes, we can implement the exact same semantics for AGs:

- A ResourceWarning will be issued if an AG is GCed and cannot be 
synchronously closed (that will happen if no finalizer is set and there 
are 'await' expressions in 'finally').

- A RuntimeError is issued when an AG is yielding (asynchronously) in 
its 'finally' block.

I think both of those things are already there in the reference 
implementation.  So we can just lift the requirement for asynchronous 
finalizer being set before you iterate an AG.

> For an async generator there are two cases: either it tries to yield 
> another value (the first time this happens you can throw an error back 
> into it) or it tries to await -- in that case you can also throw an 
> error back into it, and if the error comes out unhandled you can print 
> the error (in both cases actually).
>
> It's probably to specify all this behavior using some kind of default 
> finalizer (though you don't have to implement it that way).
>
> Hopefully there will be other discussion as well, otherwise I'll have 
> to accept the PEP once this issue is cleared up. :-)

Curious to hear your thoughts on two different approaches to 
finalization.  At this point, I'm inclined to change the PEP to use the 
second approach.  I think it gives much more power to event loops, and 
basically means that any kind of APIs to control AG (or to finalize the 
loop) is possible.

Thank you,
Yury


More information about the Python-Dev mailing list