Have there some like Goroutines in Python 3.13 or maybe 3.14

I’m aware of all that, what I was drawing attention to is that async functions in JS are run synchronously up to and including the first await expression. In Python, async(io) functions are run asynchronously in their entirety. You can read the MDN article on async functions if you wanna learn more about this distinction: async function - JavaScript | MDN.

That’s exactly what I demonstrated in Python. ‘Main completed’ is printed before ‘Task 2 completed’. I just used asyncio.sleep(3) to simulate a real-world application.

Good to know that we are on the same page!

… hookay, think I’m done with this community for a while.

@jefer94 Python async code is non-blocking (as long as there are tasks to be executed). It is not related to the GIL.

Python does not have a built-in implementation of goroutines like Go does. However, Python provides facilities such as the asyncio module for asynchronous programming and the threading module for threading, which can be used to achieve similar concurrency patterns as goroutines.

And I have found this much easier to follow.

Right now we can do this.

import asyncio

async def foo(loop):
    print('foo')
    loop.stop()

loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop) # <----
asyncio.ensure_future(foo(loop))
loop.run_forever()

We are fetching a new event loop, if we use an object similar to the event loop that manages a pool of event loops, it should act like a proxy.

import asyncio

async def foo(loop):
    print('foo')
    loop.stop()

loop = asyncio.new_event_loop_pool(10)
asyncio.set_event_loop(loop) # <----
asyncio.ensure_future(foo(loop))
loop.run_forever()

Currently, the async functions in Python feel like it was emulated and the reason to think it is

async def x():
    print('x')

async def y():
    task = x()
    print('y')
    # 7000 lines adobe
    print('z')
    await task

...

Result

y
z
x

It’s completely unnatural to have this printed at the end, I think that the design of the async function was thought out within the GIL rules.

Technically that code is not blocking but it’s unnatural to have a non-blocking code that requires to be awaited to be executed, globally it’s non-blocking but unitarily it doesn’t

Would you mind moving this thread to Help? It will get much more exposure.

Oh, I see what you mean. That’s only an issue because I made such tiny functions here, with no actual await points in them. But had both functions had other await points, they definitely WOULD have run concurrently.

My benchmark

JS

function wait(ms) {
    return new Promise(resolve => setTimeout(resolve, ms));
}

async function task1() {
    console.log('task 11')
    await wait(2000);
    console.log('task 12')
    return 2
}

async function task2() {
    console.log('task 21')
    await wait(3000);
    console.log('task 22')
    return 3
}

async function task3() {
    console.log('task 31')
    await wait(5000);
    console.log('task 32')
    return 3
}

async function main() {
    const t1 = new Date()
    const p1 = task1()
    const p2 = task2()
    const p3 = task3()

    wait(1)

    const n1 = await p1
    const n2 = await p2
    const n3 = await p3
    console.log(n1 + n2 + n3)
    const t2 = new Date()
    console.log('time elapsed:', t2 - t1)
}

main()

Python with create tasks

import asyncio
import time


async def wait(ms):
    await asyncio.sleep(ms / 1000)


async def task1():
    print('task11')
    await wait(2000)
    print('task12')
    return 2


async def task2():
    print('task21')
    await wait(3000)
    print('task22')
    return 3


async def task3():
    print('task31')
    await wait(5000)
    print('task32')
    return 3


async def main():
    t1 = time.time()

    p1 = asyncio.create_task(task1())
    p2 = asyncio.create_task(task2())
    p3 = asyncio.create_task(task3())

    await wait(1)

    n1 = await p1
    n2 = await p2
    n3 = await p3

    print(n1 + n2 + n3)

    t2 = time.time()
    print('time elapsed:', t2 - t1)


# Run the main function
asyncio.run(main())

Python with the code structured like Javascript

import asyncio
import time


async def wait(ms):
    await asyncio.sleep(ms / 1000)


async def task1():
    print('task11')
    await wait(2000)
    print('task12')
    return 2


async def task2():
    print('task21')
    await wait(3000)
    print('task22')
    return 3


async def task3():
    print('task31')
    await wait(5000)
    print('task32')
    return 3


async def main():
    t1 = time.time()

    p1 = task1()
    p2 = task2()
    p3 = task3()

    await wait(1)

    n1 = await p1
    n2 = await p2
    n3 = await p3

    print(n1 + n2 + n3)

    t2 = time.time()
    print('time elapsed:', t2 - t1)


# Run the main function
asyncio.run(main())

Results

jefer@Jeferson ~/d/w/apiv2 (feat/google-meet)> bun zz.js
task 11
task 21
task 31
task 12
task 22
task 32
8
time elapsed: 5004
jefer@Jeferson ~/d/w/apiv2 (feat/google-meet)> python zz.py
task11
task21
task31
task12
task22
task32
8
time elapsed: 5.003381013870239
jefer@Jeferson ~/d/w/apiv2 (feat/google-meet)> python zz2.py
task11
task12
task21
task22
task31
task32
8
time elapsed: 10.011826276779175