I just noticed something surprising. Consider the following example:
import asyncio
async def wait_n(n):
asyncio.sleep(n)
async def main(fn):
print("meh")
await fn(1)
print("foo")
loop = asyncio.get_event_loop()
loop.run_until_complete(main(wait_n))
When we run this, we rightfully receive the following warning:
awaitable_lambda.py:5: RuntimeWarning: coroutine 'sleep' was never awaited
asyncio.sleep(n)
This is because in wait_n we called asyncio.sleep(n) without await.
But now consider the second example:
import asyncio
async def main(fn):
print("meh")
await fn(1)
print("foo")
loop = asyncio.get_event_loop()
loop.run_until_complete(main(lambda n: asyncio.sleep(n)))
This time we are using a lambda and surprisingly the code works just fine even though there is no await.
I understand that we can not use await inside a Python lambda expression so this seems like a feature to improve ergonomics but it leads to me some questions:
- How exactly does this work? Does this simple "inject" an
awaitbefore any coroutine function? - Is this documented somewhere (PEP)?
- Are there any other implications of this? Can we just safely call coroutinefunctions from lambda expressions and rely on Python to await things for us?