'Python Asyncio - Trying to solve a simple mystery

  • This is probably the second time I've asked for help here so my apologies for little or extra detail / wording in my question *

The following code, though very basic is something I've written as an imitation (in its simplest form) of another piece of code written by an ex-employee at my firm. I am currently working on a project she was working on, and I do not understand how the following is executing without it being awaited or gathered.

In the original code, the 'wait_and_print' function is of course is an async function that that does a single RESTful web API call using aiohttp.ClientSession (using an async context manager) which returns nothing yet appends/extends a list with the response it gets.

So far, it has been 2 weeks since I've been using (and trying to understand) asyncio or asynchronous programming thus I am not very savvy with it. I've used Python, however for 3 years - on and off. I understand what task creation does and how asyncio.gather can run multiple API calls concurrently. BUT, this is something I do not get;

import asyncio
import time


L = []

async def wait_and_print(wait_time):

    print(f"starting function {wait_time}")
    for x in range(1, wait_time + 1):
        print("Sleeping for {} time.".format(x))
        await asyncio.sleep(1)
    print(f"ending function {wait_time}")
    L.append(wait_time)

async def main_loop():

    tasks = [ asyncio.create_task(wait_and_print(x)) for x in [3,1,2]]     
    while len(tasks) != 0:

        tasks = [t for t in tasks if not t.done()]

        await asyncio.sleep(0)  # HOW IS THIS MAKING IT WORK WITHOUT ACTUALLY AWAITING tasks?
    
    print("Main loop ended!")

def final(func):

    a = time.time()
    asyncio.run(func())
    b = time.time()
    print(b-a, "seconds taken to run all!")
    print(L)

final(main_loop)


Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source