Source code for a_sync.utils

"""
This module initializes the utility functions for the a_sync library, including functions for handling asynchronous 
iterators and implementing asynchronous versions of the built-in any and all functions.
"""

import asyncio

from a_sync.utils.iterators import as_yielded, exhaust_iterator, exhaust_iterators


__all__ = [
    # "all",
    # "any",
    "as_yielded",
    "exhaust_iterator",
    "exhaust_iterators",
]


[docs] async def any(*awaitables) -> bool: """ Asynchronously evaluates whether any of the given awaitables evaluates to True. This function returns True if any element in the asynchronous iterable is truthy. It short-circuits on the first truthy value. If the iterable is empty, it returns False. Args: *awaitables: A variable length list of awaitable objects. Returns: bool: True if any element is truthy, False if all are falsy or the iterable is empty. Example: >>> async def is_odd(x): ... await asyncio.sleep(0.1) # Simulate some async work ... return x % 2 != 0 ... >>> numbers = [2, 4, 6, 7] >>> result = await any(*[is_odd(x) for x in numbers]) >>> result True >>> numbers = [2, 4, 6, 8] >>> result = await any(*[is_odd(x) for x in numbers]) >>> result False Note: This function will stop iterating as soon as it encounters a truthy value. """ futs = [asyncio.ensure_future(a) for a in awaitables] for fut in asyncio.as_completed(futs): try: result = bool(await fut) except RuntimeError as e: if str(e) == "cannot reuse already awaited coroutine": raise RuntimeError(str(e), fut) from e else: raise if bool(result): for fut in futs: fut.cancel() return True return False
[docs] async def all(*awaitables) -> bool: """ Asynchronously evaluates whether all of the given awaitables evaluate to True. This function takes multiple awaitable objects and returns True if all of them evaluate to True. It cancels the remaining awaitables once a False result is found. Args: *awaitables: A variable length list of awaitable objects. Returns: bool: True if all elements are truthy or the iterable is empty, False otherwise. Example: >>> async def is_even(x): ... return x % 2 == 0 ... >>> numbers = [2, 4, 6, 8] >>> result = await all(*[is_even(x) for x in numbers]) >>> result True >>> numbers = [2, 3, 4, 6] >>> result = await all(*[is_even(x) for x in numbers]) >>> result False """ futs = [asyncio.ensure_future(a) for a in awaitables] for fut in asyncio.as_completed(futs): try: result = bool(await fut) except RuntimeError as e: if str(e) == "cannot reuse already awaited coroutine": raise RuntimeError(str(e), fut) from e else: raise if not result: for fut in futs: fut.cancel() return False return True