From f536cf9f3400e893278857117398fa452257d3b1 Mon Sep 17 00:00:00 2001 From: Abhi Agarwal Date: Sat, 11 Jan 2025 17:29:33 -0500 Subject: [PATCH] vault backup: 2025-01-11 17:29:33 --- .../running-a-bunch-of-futures-safely.md | 30 +++++++++++++++++-- 1 file changed, 27 insertions(+), 3 deletions(-) diff --git a/content/programming/languages/python/asyncio/running-a-bunch-of-futures-safely.md b/content/programming/languages/python/asyncio/running-a-bunch-of-futures-safely.md index eb890e0..b514c4b 100644 --- a/content/programming/languages/python/asyncio/running-a-bunch-of-futures-safely.md +++ b/content/programming/languages/python/asyncio/running-a-bunch-of-futures-safely.md @@ -79,13 +79,37 @@ import asyncio from collections.abc import Awaitable, Iterable from typing import TypeVar -T = TypeVar("T") +T = TypeVar("T") # for compatibility with python <=3.11 -async def run_futures(coros: Iterable[Awaitable[T]]) -> list[T]: +async def gather_tg(coros: *Awaitable[T]) -> list[T]: async with asyncio.TaskGroup() as tg: tasks: list[asyncio.Task] = [tg.create_task(coro) for coro in coros] return [t.result() for t in tasks] ``` -Now, we can use it. \ No newline at end of file +Then, we can use it: + +```python +async def func1(val: int) -> int: + return val + +async def func2(val: str) -> int: + return len(val) + +async def func3(val: str) -> str: + return val + + +async def main() -> None: + results_1 = await gather_tg(*[func1(val) for val in range(5)]) + print(results_1) # mypy thinks type is lint[int] + + results_2 = await gather_tg(func1(1), func2("4")) + print(results_2) # mypy thinks type is lint[int] + + results_3 = await gather_tg(func2("1"), func3("4")) + print(results_3) # mypy thinks type is lint[int | str] +``` + +Interestingly, `mypy` throws an error on the `[tg.create_task(coro) for coro in coros]` block, claiming that `Argument 1 to "create_task" of "TaskGroup" has incompatible type "Awaitable[T]"; expected "Coroutine[Any, Any, Any]. Mypy[arg-type]`. But... it's right. \ No newline at end of file