asyncstdlib

Async-native reimplementations of Python's builtins, itertools, functools, contextlib, and heapq for asyncio, trio, and any event loop.

Library
PyPI
v3.14.0
382stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
73/100Good
Development Activity92
Maintenance64
Community56
Maturity60
Momentum20

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
78/100Good
Architecture82
Code Quality90
Innovation58
Learning Curve80

asyncstdlib re-implements core pieces of the Python standard library — builtins like zip, map, enumerate, and sum, along with itertools, functools, contextlib, and heapq — so they work naturally with async callables, iterables, and context managers. It is fully agnostic to the event loop in use, working identically under asyncio, trio, or any custom implementation.

The library focuses on correctness around async iteration: safe cleanup of async iterators, careful handling of concurrent access in async caching, and helpers like scoped_iter and borrow that make it easy to share async iterators without accidentally closing them out from under another consumer. It ships full type stubs and is validated against mypy and pyright in strict mode.

What You Get

  • Async builtins - async versions of zip, map, filter, enumerate, iter, all, any, max, min, sum, list, dict, set, tuple, sorted, and anext.
  • Async itertools - accumulate, batched, chain, compress, cycle, dropwhile, filterfalse, groupby, islice, pairwise, starmap, takewhile, tee, and zip_longest.
  • Async functools - reduce, lru_cache, cache, and cached_property with async-safe locking for concurrent access.
  • Async contextlib - closing, ContextDecorator, contextmanager, nullcontext, and ExitStack for async context managers.
  • Iterator lifecycle helpers - borrow, scoped_iter, await_each, any_iter, apply, and sync for safely sharing and cleaning up async iterators.

Common Use Cases

  • Porting sync algorithms to async I/O - swap in async equivalents of familiar stdlib functions when refactoring code to use asyncio or trio without rewriting the iteration logic.
  • Sharing one async iterator across consumers - use borrow or scoped_iter to hand a single async generator to multiple call sites without one consumer accidentally closing it for the others.
  • Memoizing expensive async calls - use lru_cache, cache, or cached_property to avoid redundant concurrent async I/O or computation, with locking that ensures only one call proceeds per key.
  • Working across event loop implementations - build libraries or apps that need to run unmodified on asyncio, trio, or a custom event loop, since asyncstdlib makes no assumptions about the loop.

Under The Hood

Architecture The library mirrors the standard library’s own module boundaries — builtins.py, itertools.py, functools.py, contextlib.py, and heapq.py — with __init__.py re-exporting the public surface. Every public module is built on a small set of shared primitives in _core.py: aiter() normalizes sync iterables, async iterables, and callables-with-sentinel into a single async iterator protocol, ScopedIter guarantees aclose() is called on exit, and awaitify()/Awaitify coerce plain sync callables into awaitables on first use. _typing.py supplies the shared generic type variables used across every module. Because nearly every public function funnels through aiter/ScopedIter, those two abstractions are the single point that the rest of the library’s correctness depends on.

Tech Stack Pure Python with zero runtime dependencies (dependencies = [] in pyproject.toml), built with the flit_core backend and supporting CPython 3.8 through 3.14 plus PyPy 3.8/3.10. The package ships a py.typed marker alongside hand-written .pyi stubs for builtins, contextlib, functools, heapq, and the internal _lrucache module. Documentation is built with Sphinx and sphinxcontrib-trio; the project publishes to both PyPI and conda-forge.

Code Quality Each public module has a dedicated test file under unittests/ (test_builtins.py, test_itertools.py, test_functools.py, test_functools_lru.py, test_contextlib.py, test_heapq.py, test_asynctools.py), backed by shared fixtures in utility.py. CI runs the full pytest suite with coverage across seven CPython versions and two PyPy versions, in addition to separate CodeQL and zizmor security-scanning workflows. Both mypy (with disallow_untyped_defs, warn_unreachable, strict_equality, and related strict flags) and pyright in strict mode are configured against the source and its type stubs, and flake8 with flake8-bugbear enforces style.

What Makes It Unique asyncstdlib is a deliberately faithful port of stdlib semantics rather than a novel algorithm collection, but it earns its keep on the async-specific edge cases that don’t exist in synchronous code: lru_cache/cached_property use a lock-backed placeholder value so concurrent callers awaiting the same key trigger only one underlying coroutine instead of duplicating work, and ScopedIter/borrow/scoped_iter prevent one consumer of a shared async iterator from silently exhausting or closing it for another.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search