I was experimenting with creating my own awaitable object. I understand that the precise details of what __await__
returns are async-library dependent, but I was hoping I could just copy the values from another asynchronous function.
import asyncio
class MyObject:
async def ten(self):
await asyncio.sleep(.5)
print("Returning")
return 10
def __await__(self):
# Just do exactly what ten() does
yield from self.ten().__await__()
retu
async def main():
object = MyObject()
print(await object.ten())
print(await object)
if __name__ == '__main__':
asyncio.run(main())
When I ran the code, both await object.ten()
and await object
paused for half a second and then printed the message. But the former returned the value 10 while the latter returned None.
Is it possible to craft a generic __await__
function that behaves exactly like another asynchronous function, including its return value?
Yes, you just forgot return
:
def __await__(self):
# Just do exactly what ten() does
return (yield from self.ten().__await__())
This is the classic way, and return (yield from awaitable.__await__())
is equivalent to return await awaitable
in an asynchronous function. Alternatively, you can do it this way:
def __await__(self):
# Just do exactly what ten() does
return self.ten().__await__()
But then your __await__()
will not appear in stack traces, making it harder to debug for errors.