Sujet : Re: Await expressions
De : ram (at) *nospam* zedat.fu-berlin.de (Stefan Ram)
Groupes : comp.lang.pythonDate : 29. Jan 2024, 13:53:33
Autres entêtes
Organisation : Stefan Ram
Message-ID : <asyncio-20240129134136@ram.dialup.fu-berlin.de>
References : 1 2 3 4 5 6 7 8
Lawrence D'Oliveiro <
ldo@nz.invalid> writes:
It can be a tricky thing to get to grips with, particularly if you are
trying to understand how it works at a low level.
Does "await f()" (immediately) call "f()"?
To find this out, I wrote the following program.
I assume that the next function executed after executing
"await sleep()" is "sleep" and encoded this in assertions.
So far, this assumption never failed.
So, directly after the eternal task executes "await sleep()",
it is always the coroutine sleep() that starts, it never
happens that the other task continues before this happens.
Also, "caller" in "sleep" is "main", "eternal", or "other" as if
"sleep" is called from one of those (as one would naïvely expect).
So, it seems that "await f()" indeed will call f().
import asyncio as _asyncio
import inspect as _inspect
import random as _random
next = ''
async def sleep():
global next
assert next == 'sleep'
next = ''
caller = ''
frameinfo = _inspect.stack( 1 )
if frameinfo: caller = frameinfo[ 1 ].function
await _asyncio.sleep( 0.0000000001 )
async def eternal():
global next
while True:
assert next != 'sleep'
next = 'sleep'
await sleep()
async def other():
global next
while True:
assert next != 'sleep'
next = 'sleep'
await sleep()
async def main():
global next
assert next != 'sleep'
eternal_task = _asyncio.get_running_loop().create_task( eternal() )
next = 'sleep'
await sleep()
other_task = _asyncio.get_running_loop().create_task( other() )
await eternal_task
_asyncio.run( main() )