The Coroutine/Generator Issue¶
Let’s take a look at our Coroutine/Generator Issue
again now we have the new async/await syntax.
We have (mis-)used the generatorsFixed: Generators and Coroutines are separated concepts and objects now.
Generators/Iterators are intended for yielding something that is consumed by the caller.Implementation wise we have the same thing, but semantically they are very different.Fixed: Generators/Iterators are a different concept now and we have async versions of both too.
Coroutines in contrast useyieldandyield fromto just suspend the current function and give control back to the loop.We have
awaitinstead ofyield fromand suspending is carefully hidden inAwaitableslikeFuturesandTasks.From looking at the code or the object users still could mix up coroutines and generators because it relies just on a technical detail.Usingyield/yield fromsomewhere in a function declaration to make the function asynchronous is not very obvious.Fixed: By using
async deffor coroutines they are much easier to identify and prone against mixing them up.Users could still pass generators and generators could still run coroutines because nothing forbids to use coroutines as generators and the other way round.Fixed: It’s not possible to use generators as coroutines with Python 3.11 anymore.
Users could refactor a generator function that it becomes a normal function (accidentally) just becauseyield/yield fromis removed.Fixed: Can’t happen with
async def. The identity of a coroutine doesn’t depend on a statement within the function. It is already settled during the function definition.