asyncio loop.call_soon()

Ian Kelly ian.g.kelly at gmail.com
Tue Nov 28 11:02:59 EST 2017


On Tue, Nov 28, 2017 at 8:30 AM, ast <nomail at com.invalid> wrote:
> Hello
>
> Python's doc says about loop.call_soon(callback, *arg):
>
> Arrange for a callback to be called as soon as possible. The callback is
> called after call_soon() returns, when control returns to the event loop.
>
> But it doesn't seem to be true; see this program:
>
> import asyncio
>
> async def task_func():
>    print("Entering task_func")
>
> def callback():
>    print("Entering callback")
>
> async def main():
>    print("Entering main")
>    task = loop.create_task(task_func())
>    loop.call_soon(callback)
>    await task
>
> loop = asyncio.get_event_loop()
> loop.run_until_complete(main())
>
> Execution provides following output:
>
> Entering main
> Entering task_func
> Entering callback
>
> callback is executed AFTER task_func, I expected it
> to be executed BEFORE.
>
> When "main()" coroutine reach line "await task", it let the control to the
> event loop, and it seems that the loop starts to execute task instead of
> callback. Then, when task is over the loop runs callback
>
> This is not what the doc says: callback should be called as soon
> as possible when the loop has control, with a priority over other
> tasks pending in the loop

You omitted this part of the documentation:

"This operates as a FIFO queue, callbacks are called in the order in
which they are registered. Each callback will be called exactly once."

This documents the ordering of call_soon callbacks. It doesn't say
anything about how the callback will be ordered with respect to tasks
or other events that are also immediately ready to be handled.

Also, if you look at the implementation of create_task, it invokes
call_soon. This is therefore consistent with the doc, as call_soon was
actually called twice: first for task_func(), and then for callback.



More information about the Python-list mailing list