The missing async toolbox

Documentation Status Available on PyPI Available on Conda-Forge License Development Chat

The asyncstdlib library re-implements functions and classes of the Python standard library to make them compatible with async callables, iterables and context managers. It is fully agnostic to async event loops and seamlessly works with asyncio, third-party libraries such as trio, as well as any custom async event loop.

Standard Library Modules

All re-implementations are located in submodules of asyncstdlib with the same name as those of the Python standard library.

asyncstdlib.builtins

Replicates any Built-in Functions that benefit from being asynchronous, such as zip(), sum(), or list().

asyncstdlib.functools

Replicates any functools that benefit from being asynchronous, which is just reduce(), cached_property(), and lru_cache().

asyncstdlib.contextlib

Replicates any contextlib tools that benefit from being asynchronous, such as contextmanager(), or closing().

asyncstdlib.itertools

Replicates any itertools that benefit from being asynchronous, such as cycle(), chain(), or accumulate().

For simplicity, the asyncstdlib namespace also exposes all individual functions and classes directly. For example, asyncstdlib.builtins.enumerate is also available as asyncstdlib.enumerate.

The Async Library Module

The core toolset used by asyncstdlib itself is available as a separate submodule.

asyncstdlib.asynctools

Collects any asyncstdlib tools useful for building well-behaved async helpers and programs.

Async Neutral Arguments

Many objects of asyncstdlib are async neutral – they accept both regular and async arguments. Type annotations use (async) to denote async neutral objects. For example, the annotation (int, …) → (async) bool denotes a call that takes an int and either returns a boolean directly or requires await to return a boolean.

Whether a call is regular or async is determined by inspecting its return type at runtime. This supports async-producing factories, such as an async def function wrapped in functools.partial. However, this also means that the result must consistently be either regular or async.

Note that only arguments to asyncstdlib may be async neutral. All callables of asyncstdlib consistently provide awaitables, asynchronous iterators, and asynchronous context managers.

Async Iterator Cleanup

Cleanup of async iterables is special in that aclose() may require an active event loop. This is not given when garbage collection finalizes an async iterable via its __del__() method. Thus, async iterators should be cleaned up deterministically whenever possible (see PEP 533 for details).

All async iterators of asyncstdlib that work on other iterators assume sole ownership of the iterators passed to them. Passed in async iterators are guaranteed to aclose() as soon as the asyncstdlib async iterator itself is cleaned up. Use borrow() to prevent automatic cleanup, and scoped_iter() to guarantee cleanup in custom code.

Indices and tables