From 6f9efc37f6b4f02d30f44ddbfeef1440b6ec24e0 Mon Sep 17 00:00:00 2001 From: BobTheBuidler <70677534+BobTheBuidler@users.noreply.github.com> Date: Fri, 16 Feb 2024 09:28:26 -0500 Subject: [PATCH] chore: fix mypy errs (#127) --- a_sync/_bound.py | 2 +- a_sync/_typing.py | 8 +++---- a_sync/base.py | 2 +- a_sync/iter.py | 2 +- a_sync/primitives/executor.py | 2 +- a_sync/primitives/locks/semaphore.py | 2 +- a_sync/property.py | 2 +- a_sync/task.py | 3 ++- a_sync/utils/as_completed.py | 34 +++++++++++++--------------- a_sync/utils/gather.py | 21 ++++++++--------- a_sync/utils/iterators.py | 22 +++++++++--------- 11 files changed, 48 insertions(+), 52 deletions(-) diff --git a/a_sync/_bound.py b/a_sync/_bound.py index 51b44ddb..2b02bbcd 100644 --- a/a_sync/_bound.py +++ b/a_sync/_bound.py @@ -16,7 +16,7 @@ def _clean_default_from_modifiers( coro_fn: AsyncBoundMethod[P, T], # type: ignore [misc] - modifiers: dict + modifiers: ModifierKwargs, ): # NOTE: We set the default here manually because the default set by the user will be used later in the code to determine whether to await. force_await = None diff --git a/a_sync/_typing.py b/a_sync/_typing.py index 4e312b71..bfec8215 100644 --- a/a_sync/_typing.py +++ b/a_sync/_typing.py @@ -3,10 +3,10 @@ from concurrent.futures._base import Executor from decimal import Decimal from typing import (TYPE_CHECKING, Any, AsyncIterable, AsyncIterator, Awaitable, - Callable, DefaultDict, Deque, Dict, Generator, Generic, - ItemsView, Iterable, Iterator, KeysView, List, Literal, - Optional, Protocol, Set, Tuple, Type, TypedDict, TypeVar, - Union, ValuesView, final, overload) + Callable, Coroutine, DefaultDict, Deque, Dict, Generator, + Generic, ItemsView, Iterable, Iterator, KeysView, List, Literal, + Mapping, Optional, Protocol, Set, Tuple, Type, TypedDict, + TypeVar, Union, ValuesView, final, overload) from typing_extensions import Concatenate, ParamSpec, Self, Unpack diff --git a/a_sync/base.py b/a_sync/base.py index 0ac32d46..d39f9cd7 100644 --- a/a_sync/base.py +++ b/a_sync/base.py @@ -59,7 +59,7 @@ def __a_sync_default_mode__(cls) -> bool: # type: ignore [override] return sync @classmethod - def __get_a_sync_flag_name_from_signature(cls) -> str: + def __get_a_sync_flag_name_from_signature(cls) -> Optional[str]: logger.debug("Searching for flags defined on %s.__init__", cls) if cls.__name__ == "ASyncGenericBase": logger.debug("There are no flags defined on the base class, this is expected. Skipping.") diff --git a/a_sync/iter.py b/a_sync/iter.py index ba2729f1..0fc950bf 100644 --- a/a_sync/iter.py +++ b/a_sync/iter.py @@ -25,7 +25,7 @@ def wrap(self, aiterator: AsyncIterator[T]) -> "ASyncWrappedIterator[T]": class ASyncWrappedIterable(ASyncIterable[T]): def __init__(self, async_iterable: AsyncIterable[T]): self.__aiterable = async_iterable - def __aiter__(self) -> AsyncIterable[T]: + def __aiter__(self) -> AsyncIterator[T]: return self.__aiterable.__aiter__() class ASyncWrappedIterator(ASyncIterator[T]): diff --git a/a_sync/primitives/executor.py b/a_sync/primitives/executor.py index daaa2f9f..af5c32e9 100644 --- a/a_sync/primitives/executor.py +++ b/a_sync/primitives/executor.py @@ -38,7 +38,7 @@ def submit(self, fn: Callable[P, T], *args: P.args, **kwargs: P.kwargs) -> "asyn if self.sync_mode: fut = asyncio.ensure_future(self._exec_sync(fn, *args, **kwargs)) else: - fut = asyncio.futures.wrap_future(super().submit(fn, *args, **kwargs)) + fut = asyncio.futures.wrap_future(super().submit(fn, *args, **kwargs)) # type: ignore [assignment] self._start_debug_daemon(fut, fn, *args, **kwargs) return fut def __repr__(self) -> str: diff --git a/a_sync/primitives/locks/semaphore.py b/a_sync/primitives/locks/semaphore.py index f22ea4fb..1a0f660b 100644 --- a/a_sync/primitives/locks/semaphore.py +++ b/a_sync/primitives/locks/semaphore.py @@ -20,7 +20,7 @@ def __init__(self, value: int, name=None, **kwargs) -> None: # Dank new functionality def __call__(self, fn: Callable[P, T]) -> Callable[P, T]: - return self.decorate(fn) + return self.decorate(fn) # type: ignore [arg-type, return-value] def __repr__(self) -> str: representation = f"<{self.__class__.__name__} name={self.name} value={self._value} waiters={len(self)}>" diff --git a/a_sync/property.py b/a_sync/property.py index c9ab06d7..d9fceb3b 100644 --- a/a_sync/property.py +++ b/a_sync/property.py @@ -54,7 +54,7 @@ def a_sync_property( # type: ignore [misc] func = None def modifier_wrap(func: Property[T]) -> AsyncPropertyDescriptor[T]: return AsyncPropertyDescriptor(func, **modifiers) - return modifier_wrap if func is None else modifier_wrap(func) + return modifier_wrap if func is None else modifier_wrap(func) # type: ignore [arg-type] @overload diff --git a/a_sync/task.py b/a_sync/task.py index 31cd7f56..6a0f2733 100644 --- a/a_sync/task.py +++ b/a_sync/task.py @@ -29,6 +29,7 @@ def __init__(self, coro_fn: MappingFn[K, P, V] = None, *iterables: AnyIterable[K self._coro_fn = coro_fn self._coro_fn_kwargs = coro_fn_kwargs self._name = name + self._loader: Optional["asyncio.Task[None]"] if iterables: self._loader = create_task(exhaust_iterator(self._tasks_for_iterables(*iterables))) else: @@ -48,7 +49,7 @@ def __getitem__(self, item: K) -> "asyncio.Task[V]": def __await__(self) -> Generator[Any, None, Dict[K, V]]: """await all tasks and returns a mapping with the results for each key""" return self._await().__await__() - async def __aiter__(self) -> Union[AsyncIterator[Tuple[K, V]], AsyncIterator[K]]: + async def __aiter__(self) -> AsyncIterator[Tuple[K, V]]: """aiterate thru all key-task pairs, yielding the key-result pair as each task completes""" yielded = set() # if you inited the TaskMapping with some iterators, we will load those diff --git a/a_sync/utils/as_completed.py b/a_sync/utils/as_completed.py index 1742bcbf..06c11a97 100644 --- a/a_sync/utils/as_completed.py +++ b/a_sync/utils/as_completed.py @@ -1,8 +1,5 @@ import asyncio -from typing import (Any, AsyncIterator, Awaitable, Coroutine, Iterable, - Iterator, Literal, Mapping, Optional, Tuple, TypeVar, - Union, overload) try: from tqdm.asyncio import tqdm_asyncio @@ -11,12 +8,9 @@ class tqdm_asyncio: # type: ignore [no-redef] def as_completed(*args, **kwargs): raise ImportError("You must have tqdm installed to use this feature") +from a_sync._typing import * from a_sync.iter import ASyncIterator -T = TypeVar('T') -KT = TypeVar('KT') -VT = TypeVar('VT') - @overload def as_completed(fs: Iterable[Awaitable[T]], *, timeout: Optional[float] = None, return_exceptions: bool = False, aiter: Literal[False] = False, tqdm: bool = False, **tqdm_kwargs: Any) -> Iterator[Coroutine[None, None, T]]: ... @@ -24,10 +18,10 @@ def as_completed(fs: Iterable[Awaitable[T]], *, timeout: Optional[float] = None, def as_completed(fs: Iterable[Awaitable[T]], *, timeout: Optional[float] = None, return_exceptions: bool = False, aiter: Literal[True] = True, tqdm: bool = False, **tqdm_kwargs: Any) -> ASyncIterator[T]: ... @overload -def as_completed(fs: Mapping[KT, Awaitable[VT]], *, timeout: Optional[float] = None, return_exceptions: bool = False, aiter: Literal[False] = False, tqdm: bool = False, **tqdm_kwargs: Any) -> Iterator[Coroutine[None, None, Tuple[KT, VT]]]: +def as_completed(fs: Mapping[K, Awaitable[V]], *, timeout: Optional[float] = None, return_exceptions: bool = False, aiter: Literal[False] = False, tqdm: bool = False, **tqdm_kwargs: Any) -> Iterator[Coroutine[None, None, Tuple[K, V]]]: ... @overload -def as_completed(fs: Mapping[KT, Awaitable[VT]], *, timeout: Optional[float] = None, return_exceptions: bool = False, aiter: Literal[True] = True, tqdm: bool = False, **tqdm_kwargs: Any) -> ASyncIterator[Tuple[KT, VT]]: +def as_completed(fs: Mapping[K, Awaitable[V]], *, timeout: Optional[float] = None, return_exceptions: bool = False, aiter: Literal[True] = True, tqdm: bool = False, **tqdm_kwargs: Any) -> ASyncIterator[Tuple[K, V]]: ... def as_completed(fs, *, timeout: Optional[float] = None, return_exceptions: bool = False, aiter: bool = False, tqdm: bool = False, **tqdm_kwargs: Any): """ @@ -42,7 +36,7 @@ def as_completed(fs, *, timeout: Optional[float] = None, return_exceptions: bool - Provides progress reporting using tqdm if 'tqdm' is set to True. Args: - fs (Iterable[Awaitable[T] or Mapping[KT, Awaitable[VT]]]): The awaitables to await concurrently. It can be a list of individual awaitables or a mapping of awaitables. + fs (Iterable[Awaitable[T] or Mapping[K, Awaitable[V]]]): The awaitables to await concurrently. It can be a list of individual awaitables or a mapping of awaitables. timeout (float, optional): The maximum time, in seconds, to wait for the completion of awaitables. Defaults to None (no timeout). return_exceptions (bool, optional): If True, exceptions are returned as results instead of raising them. Defaults to False. aiter (bool, optional): If True, returns an async iterator of results. Defaults to False. @@ -50,7 +44,7 @@ def as_completed(fs, *, timeout: Optional[float] = None, return_exceptions: bool **tqdm_kwargs: Additional keyword arguments for tqdm if progress reporting is enabled. Returns: - Iterator[Coroutine[None, None, T] or ASyncIterator[Tuple[KT, VT]]]: An iterator of results when awaiting individual awaitables or an async iterator when awaiting mappings. + Iterator[Coroutine[None, None, T] or ASyncIterator[Tuple[K, V]]]: An iterator of results when awaiting individual awaitables or an async iterator when awaiting mappings. Examples: Awaiting individual awaitables: @@ -87,19 +81,19 @@ def as_completed(fs, *, timeout: Optional[float] = None, return_exceptions: bool ) @overload -def as_completed_mapping(mapping: Mapping[KT, Awaitable[VT]], *, timeout: Optional[float] = None, return_exceptions: bool = False, aiter: Literal[True] = True, tqdm: bool = False, **tqdm_kwargs: Any) -> ASyncIterator[Tuple[KT, VT]]: +def as_completed_mapping(mapping: Mapping[K, Awaitable[V]], *, timeout: Optional[float] = None, return_exceptions: bool = False, aiter: Literal[True] = True, tqdm: bool = False, **tqdm_kwargs: Any) -> ASyncIterator[Tuple[K, V]]: ... @overload -def as_completed_mapping(mapping: Mapping[KT, Awaitable[VT]], *, timeout: Optional[float] = None, return_exceptions: bool = False, aiter: Literal[False] = False, tqdm: bool = False, **tqdm_kwargs: Any) -> Iterator[Coroutine[None, None, Tuple[KT, VT]]]: +def as_completed_mapping(mapping: Mapping[K, Awaitable[V]], *, timeout: Optional[float] = None, return_exceptions: bool = False, aiter: Literal[False] = False, tqdm: bool = False, **tqdm_kwargs: Any) -> Iterator[Coroutine[None, None, Tuple[K, V]]]: ... -def as_completed_mapping(mapping: Mapping[KT, Awaitable[VT]], *, timeout: Optional[float] = None, return_exceptions: bool = False, aiter: bool = False, tqdm: bool = False, **tqdm_kwargs: Any) -> Union[Iterator[Coroutine[None, None, Tuple[KT, VT]]], ASyncIterator[Tuple[KT, VT]]]: +def as_completed_mapping(mapping: Mapping[K, Awaitable[V]], *, timeout: Optional[float] = None, return_exceptions: bool = False, aiter: bool = False, tqdm: bool = False, **tqdm_kwargs: Any) -> Union[Iterator[Coroutine[None, None, Tuple[K, V]]], ASyncIterator[Tuple[K, V]]]: """ Concurrently awaits a mapping of awaitable objects and returns an iterator or async iterator of results. This function is designed to await a mapping of awaitable objects, where each key-value pair represents a unique awaitable. It enables concurrent execution and gathers results into an iterator or an async iterator. Args: - mapping (Mapping[KT, Awaitable[VT]]): A dictionary-like object where keys are of type KT and values are awaitable objects of type VT. + mapping (Mapping[K, Awaitable[V]]): A dictionary-like object where keys are of type K and values are awaitable objects of type V. timeout (float, optional): The maximum time, in seconds, to wait for the completion of awaitables. Defaults to None (no timeout). return_exceptions (bool, optional): If True, exceptions are returned as results instead of raising them. Defaults to False. aiter (bool, optional): If True, returns an async iterator of results. Defaults to False. @@ -107,7 +101,7 @@ def as_completed_mapping(mapping: Mapping[KT, Awaitable[VT]], *, timeout: Option **tqdm_kwargs: Additional keyword arguments for tqdm if progress reporting is enabled. Returns: - Union[Iterator[Coroutine[None, None, Tuple[KT, VT]]] or ASyncIterator[Tuple[KT, VT]]]: An iterator of results or an async iterator when awaiting mappings. + Union[Iterator[Coroutine[None, None, Tuple[K, V]]] or ASyncIterator[Tuple[K, V]]]: An iterator of results or an async iterator when awaiting mappings. Example: ``` @@ -126,8 +120,12 @@ def as_completed_mapping(mapping: Mapping[KT, Awaitable[VT]], *, timeout: Option async def __yield_as_completed(futs: Iterable[Awaitable[T]], *, timeout: Optional[float] = None, return_exceptions: bool = False, tqdm: bool = False, **tqdm_kwargs: Any) -> AsyncIterator[T]: for fut in as_completed(futs, timeout=timeout, return_exceptions=return_exceptions, tqdm=tqdm, **tqdm_kwargs): yield await fut - -async def __mapping_wrap(k: KT, v: Awaitable[VT], return_exceptions: bool = False) -> VT: + +@overload +async def __mapping_wrap(k: K, v: Awaitable[V], return_exceptions: Literal[True] = True) -> Union[V, Exception]:... +@overload +async def __mapping_wrap(k: K, v: Awaitable[V], return_exceptions: Literal[False] = False) -> V:... +async def __mapping_wrap(k: K, v: Awaitable[V], return_exceptions: bool = False) -> Union[V, Exception]: try: return k, await v except Exception as e: diff --git a/a_sync/utils/gather.py b/a_sync/utils/gather.py index a7266f9b..ebb32570 100644 --- a/a_sync/utils/gather.py +++ b/a_sync/utils/gather.py @@ -13,20 +13,17 @@ async def gather(*args, **kwargs): from a_sync._typing import * from a_sync.utils.as_completed import as_completed_mapping -T = TypeVar('T') -KT = TypeVar('KT') -VT = TypeVar('VT') Excluder = Callable[[T], bool] @overload async def gather( - *awaitables: Mapping[KT, Awaitable[VT]], + *awaitables: Mapping[K, Awaitable[V]], return_exceptions: bool = False, exclude_if: Optional[Excluder[T]] = None, tqdm: bool = False, **tqdm_kwargs: Any, -) -> Dict[KT, VT]: +) -> Dict[K, V]: ... @overload async def gather( @@ -38,12 +35,12 @@ async def gather( ) -> List[T]: ... async def gather( - *awaitables: Union[Awaitable[T], Mapping[KT, Awaitable[VT]]], + *awaitables: Union[Awaitable[T], Mapping[K, Awaitable[V]]], return_exceptions: bool = False, exclude_if: Optional[Excluder[T]] = None, tqdm: bool = False, **tqdm_kwargs: Any, -) -> Union[List[T], Dict[KT, VT]]: +) -> Union[List[T], Dict[K, V]]: """ Concurrently awaits a list of awaitable objects or mappings of awaitables and returns the results. @@ -55,13 +52,13 @@ async def gather( - Provides progress reporting using tqdm if 'tqdm' is set to True. Args: - *awaitables (Union[Awaitable[T], Mapping[KT, Awaitable[VT]]]): The awaitables to await concurrently. It can be a single awaitable or a mapping of awaitables. + *awaitables (Union[Awaitable[T], Mapping[K, Awaitable[V]]]): The awaitables to await concurrently. It can be a single awaitable or a mapping of awaitables. return_exceptions (bool, optional): If True, exceptions are returned as results instead of raising them. Defaults to False. tqdm (bool, optional): If True, enables progress reporting using tqdm. Defaults to False. **tqdm_kwargs: Additional keyword arguments for tqdm if progress reporting is enabled. Returns: - Union[List[T], Dict[KT, VT]]: A list of results when awaiting individual awaitables or a dictionary of results when awaiting mappings. + Union[List[T], Dict[K, V]]: A list of results when awaiting individual awaitables or a dictionary of results when awaiting mappings. Examples: Awaiting individual awaitables: @@ -86,20 +83,20 @@ async def gather( results = [r for r in results if not exclude_if(r)] return results -async def gather_mapping(mapping: Mapping[KT, Awaitable[VT]], return_exceptions: bool = False, tqdm: bool = False, **tqdm_kwargs: Any) -> Dict[KT, VT]: +async def gather_mapping(mapping: Mapping[K, Awaitable[V]], return_exceptions: bool = False, tqdm: bool = False, **tqdm_kwargs: Any) -> Dict[K, V]: """ Concurrently awaits a mapping of awaitable objects and returns a dictionary of results. This function is designed to await a mapping of awaitable objects, where each key-value pair represents a unique awaitable. It enables concurrent execution and gathers results into a dictionary. Args: - mapping (Mapping[KT, Awaitable[VT]]): A dictionary-like object where keys are of type KT and values are awaitable objects of type VT. + mapping (Mapping[K, Awaitable[V]]): A dictionary-like object where keys are of type K and values are awaitable objects of type V. return_exceptions (bool, optional): If True, exceptions are returned as results instead of raising them. Defaults to False. tqdm (bool, optional): If True, enables progress reporting using tqdm. Defaults to False. **tqdm_kwargs: Additional keyword arguments for tqdm if progress reporting is enabled. Returns: - Dict[KT, VT]: A dictionary with keys corresponding to the keys of the input mapping and values containing the results of the corresponding awaitables. + Dict[K, V]: A dictionary with keys corresponding to the keys of the input mapping and values containing the results of the corresponding awaitables. Example: The 'results' dictionary will contain the awaited results, where keys match the keys in the 'mapping' and values contain the results of the corresponding awaitables. diff --git a/a_sync/utils/iterators.py b/a_sync/utils/iterators.py index 778f9148..de3b89f0 100644 --- a/a_sync/utils/iterators.py +++ b/a_sync/utils/iterators.py @@ -33,27 +33,27 @@ async def exhaust_iterators(iterators, *, queue: Optional[asyncio.Queue] = None) T9 = TypeVar('T9') @overload -async def as_yielded(*iterators: AsyncIterator[T]) -> AsyncIterator[T]:... +def as_yielded(*iterators: AsyncIterator[T]) -> AsyncIterator[T]:... @overload -async def as_yielded(iterator0: AsyncIterator[T0], iterator1: AsyncIterator[T1], iterator2: AsyncIterator[T2], iterator3: AsyncIterator[T3], iterator4: AsyncIterator[T4], iterator5: AsyncIterator[T5], iterator6: AsyncIterator[T6], iterator7: AsyncIterator[T7], iterator8: AsyncIterator[T8], iterator9: AsyncIterator[T9]) -> AsyncIterator[Union[T0, T1, T2, T3, T4, T5, T6, T7, T8, T9]]:... +def as_yielded(iterator0: AsyncIterator[T0], iterator1: AsyncIterator[T1], iterator2: AsyncIterator[T2], iterator3: AsyncIterator[T3], iterator4: AsyncIterator[T4], iterator5: AsyncIterator[T5], iterator6: AsyncIterator[T6], iterator7: AsyncIterator[T7], iterator8: AsyncIterator[T8], iterator9: AsyncIterator[T9]) -> AsyncIterator[Union[T0, T1, T2, T3, T4, T5, T6, T7, T8, T9]]:... @overload -async def as_yielded(iterator0: AsyncIterator[T0], iterator1: AsyncIterator[T1], iterator2: AsyncIterator[T2], iterator3: AsyncIterator[T3], iterator4: AsyncIterator[T4], iterator5: AsyncIterator[T5], iterator6: AsyncIterator[T6], iterator7: AsyncIterator[T7], iterator8: AsyncIterator[T8]) -> AsyncIterator[Union[T0, T1, T2, T3, T4, T5, T6, T7, T8]]:... +def as_yielded(iterator0: AsyncIterator[T0], iterator1: AsyncIterator[T1], iterator2: AsyncIterator[T2], iterator3: AsyncIterator[T3], iterator4: AsyncIterator[T4], iterator5: AsyncIterator[T5], iterator6: AsyncIterator[T6], iterator7: AsyncIterator[T7], iterator8: AsyncIterator[T8]) -> AsyncIterator[Union[T0, T1, T2, T3, T4, T5, T6, T7, T8]]:... @overload -async def as_yielded(iterator0: AsyncIterator[T0], iterator1: AsyncIterator[T1], iterator2: AsyncIterator[T2], iterator3: AsyncIterator[T3], iterator4: AsyncIterator[T4], iterator5: AsyncIterator[T5], iterator6: AsyncIterator[T6], iterator7: AsyncIterator[T7]) -> AsyncIterator[Union[T0, T1, T2, T3, T4, T5, T6, T7]]:... +def as_yielded(iterator0: AsyncIterator[T0], iterator1: AsyncIterator[T1], iterator2: AsyncIterator[T2], iterator3: AsyncIterator[T3], iterator4: AsyncIterator[T4], iterator5: AsyncIterator[T5], iterator6: AsyncIterator[T6], iterator7: AsyncIterator[T7]) -> AsyncIterator[Union[T0, T1, T2, T3, T4, T5, T6, T7]]:... @overload -async def as_yielded(iterator0: AsyncIterator[T0], iterator1: AsyncIterator[T1], iterator2: AsyncIterator[T2], iterator3: AsyncIterator[T3], iterator4: AsyncIterator[T4], iterator5: AsyncIterator[T5], iterator6: AsyncIterator[T6]) -> AsyncIterator[Union[T0, T1, T2, T3, T4, T5, T6]]:... +def as_yielded(iterator0: AsyncIterator[T0], iterator1: AsyncIterator[T1], iterator2: AsyncIterator[T2], iterator3: AsyncIterator[T3], iterator4: AsyncIterator[T4], iterator5: AsyncIterator[T5], iterator6: AsyncIterator[T6]) -> AsyncIterator[Union[T0, T1, T2, T3, T4, T5, T6]]:... @overload -async def as_yielded(iterator0: AsyncIterator[T0], iterator1: AsyncIterator[T1], iterator2: AsyncIterator[T2], iterator3: AsyncIterator[T3], iterator4: AsyncIterator[T4], iterator5: AsyncIterator[T5]) -> AsyncIterator[Union[T0, T1, T2, T3, T4, T5]]:... +def as_yielded(iterator0: AsyncIterator[T0], iterator1: AsyncIterator[T1], iterator2: AsyncIterator[T2], iterator3: AsyncIterator[T3], iterator4: AsyncIterator[T4], iterator5: AsyncIterator[T5]) -> AsyncIterator[Union[T0, T1, T2, T3, T4, T5]]:... @overload -async def as_yielded(iterator0: AsyncIterator[T0], iterator1: AsyncIterator[T1], iterator2: AsyncIterator[T2], iterator3: AsyncIterator[T3], iterator4: AsyncIterator[T4]) -> AsyncIterator[Union[T0, T1, T2, T3, T4]]:... +def as_yielded(iterator0: AsyncIterator[T0], iterator1: AsyncIterator[T1], iterator2: AsyncIterator[T2], iterator3: AsyncIterator[T3], iterator4: AsyncIterator[T4]) -> AsyncIterator[Union[T0, T1, T2, T3, T4]]:... @overload -async def as_yielded(iterator0: AsyncIterator[T0], iterator1: AsyncIterator[T1], iterator2: AsyncIterator[T2], iterator3: AsyncIterator[T3]) -> AsyncIterator[Union[T0, T1, T2, T3]]:... +def as_yielded(iterator0: AsyncIterator[T0], iterator1: AsyncIterator[T1], iterator2: AsyncIterator[T2], iterator3: AsyncIterator[T3]) -> AsyncIterator[Union[T0, T1, T2, T3]]:... @overload -async def as_yielded(iterator0: AsyncIterator[T0], iterator1: AsyncIterator[T1], iterator2: AsyncIterator[T2]) -> AsyncIterator[Union[T0, T1, T2]]:... +def as_yielded(iterator0: AsyncIterator[T0], iterator1: AsyncIterator[T1], iterator2: AsyncIterator[T2]) -> AsyncIterator[Union[T0, T1, T2]]:... @overload -async def as_yielded(iterator0: AsyncIterator[T0], iterator1: AsyncIterator[T1]) -> AsyncIterator[Union[T0, T1]]:... +def as_yielded(iterator0: AsyncIterator[T0], iterator1: AsyncIterator[T1]) -> AsyncIterator[Union[T0, T1]]:... @overload -async def as_yielded(iterator0: AsyncIterator[T0], iterator1: AsyncIterator[T1], iterator2: AsyncIterator[T2], *iterators: AsyncIterator[T]) -> AsyncIterator[Union[T0, T1, T2, T]]:... +def as_yielded(iterator0: AsyncIterator[T0], iterator1: AsyncIterator[T1], iterator2: AsyncIterator[T2], *iterators: AsyncIterator[T]) -> AsyncIterator[Union[T0, T1, T2, T]]:... async def as_yielded(*iterators: AsyncIterator[T]) -> AsyncIterator[T]: # type: ignore [misc] queue = Queue() task = asyncio.create_task(exhaust_iterators(iterators, queue=queue))