The Python Language Reference specifies object.__await__
as follows:
object.__await__(self)
Must return an iterator. Should be used to implement awaitable objects. For instance,
asyncio.Future
implements this method to be compatible with the await expression.
That's it. I find this specification very vague and not very specific (ironically). Ok, it should return an iterator, but can it be an arbitrary iterator? Obviously not:
import asyncio
class Spam:
def __await__(self):
yield from range(10)
async def main():
await Spam()
asyncio.run(main())
RuntimeError: Task got bad yield: 0
I'm assuming the asyncio
event loop expects a specific kind of object being yielded by the iterator. Then what exactly should it yield? (And why isn't this documented?)
Edit: as far as I can see, this isn't documented anywhere. But I've been investigating on my own, and I think that the key to understanding what objects the asyncio
expects its coroutines to yield lies in task_step_impl
in _asynciomodule.c
.
Update: I've made a PR to the cpython repository with the aim of clarifying this: "Clarify the vague specification of object.__await__
".
The PR has now been merged and should be available in the docs for Python 3.10+.