anext()

The half of the async protocol you actually await. Its optional default turns exhaustion from an exception into a value, exactly like next.

Built-in functionPython 3.10+
Common call
item = await anext(it)
Returns
the next item — or the default when the iterator is done
Replaces
await it.__anext__() plus a try block
Watch out
always await it; a bare anext(it) is an un-awaited coroutine
anext(async_iterator[, default])
awaitable

Parameters

NameTypeRequiredDescription
async_iteratorasync iteratoryesAn object implementing __anext__, usually obtained from aiter or an async generator.
defaultAnynoReturned instead of raising StopAsyncIteration when the iterator is exhausted.

Return value

awaitableAn awaitable yielding the next item. Without a default, exhaustion raises StopAsyncIteration; with one, the default is returned instead.

Examples

1. Next item
item = await anext(it)
Returns
the next value
2. With a default
item = await anext(it, None)
Returns
None when exhausted
3. Exhausted raises
await anext(empty_it)
Returns
StopAsyncIteration
4. Peek the first
it = aiter(stream) first = await anext(it)
Returns
first item, rest still available
5. Forgetting await
item = anext(it) type(item)
Returns
a coroutine, not the item
6. The 3.9 form
item = await it.__anext__()
Returns
same result, older syntax

Pitfalls

1. Forgetting the await
anext returns an awaitable, so without await you get a coroutine object. Python warns that it was never awaited — but only at collection time, far from the line that caused it.
A coroutine
item = anext(it)
print(item)
<coroutine object anext at 0x...>
Await it
item = await anext(it)
the actual item
2. StopAsyncIteration is not StopIteration
Async exhaustion raises its own exception type. A handler written for StopIteration does not catch it, and the error escapes as an unhandled exception.
Wrong exception
try:
    await anext(it)
except StopIteration:
    ...
StopAsyncIteration escapes
Catch the right one
try:
    await anext(it)
except StopAsyncIteration:
    ...
handled
3. Never let StopAsyncIteration escape a generator
Like StopIteration in a sync generator, letting it propagate out of an async generator turns into a RuntimeError rather than ending the loop. Always pass a default or catch it.
Leaks out
async def g(it):
    while True:
        yield await anext(it)
RuntimeError: async generator raised StopAsyncIteration
Use a sentinel
async def g(it):
    while (v := await anext(it, _MISSING)) is not _MISSING:
        yield v
ends cleanly
4. Python 3.10 and newer only
The protocol has existed since 3.5, but the builtin arrived in 3.10. Older code calls the dunder directly and hand-rolls the default.
Fails on 3.9
await anext(it)
NameError: name 'anext' is not defined
Call the dunder
await it.__anext__()
works from 3.5

When to use

Use it
  • Taking just the first item from an async stream
  • Manual stepping where async for would be too rigid
  • Merging or interleaving several async iterators by hand
  • Async helpers that need a default instead of an exception
Reach for something else
  • Consuming everything in order → async for
  • Synchronous iterators → next
  • Supporting Python 3.9 or older without a fallback

Notes

Complexity
O(1) per call, plus whatever work the iterator does to produce the item
Return
An awaitable; the item only exists once it is awaited
CPython impl
Python/bltinmodule.c :: builtin_anext
Memory
Allocates one coroutine per call
Thread-safe
Bound to its event loop — do not advance one iterator from several tasks at once

FAQ

Producing the next item may involve real I/O — a network read, a database row — so __anext__ is a coroutine. Getting the iterator does no work at all, so __aiter__ stays an ordinary method.

it = aiter(stream)          # sync
item = await anext(it)      # async

History

3.5
Async iteration protocol introduced by PEP 492 (__aiter__ and __anext__).
3.10
anext and aiter added as builtins, mirroring next and iter.