I have a code: import asyncio as aio async def coro(future: aio.Future): print('Coro start') await aio.sleep(3) print('Coro finish') future.set_result('coro result') async def main(): future = aio.Future() aio.create_task(coro(future)) await future coro_result = future.result() print(coro_result) aio.run(main()) In main() I create an empty aio.Future object, then I create a task with aio.create_task(coro(future)) using coroutine which takes aio.Future object. Then I 'run' the empty future with await future. Somehow this line runs the task instead of running the empty coroutine! I don't understand how it works and why it goes like this, because I expect the line await future to run the empty future, not task! If I reorganize my main() like this: import asyncio as aio async def coro(future: aio.Future): print('Coro start') await aio.sleep(3) print('Coro finish') future.set_result('coro result') async def main(): future = aio.Future() await aio.create_task(coro(future)) # await future coro_result = future.result() print(coro_result) aio.run(main()) I get the same result but the code behaviour becomes much more explicit for me. Continue reading...