Skip to content

gh-64862: Add the stop_exception parameter in iter() and aiter() - #156298

Open
serhiy-storchaka wants to merge 4 commits into
python:mainfrom
serhiy-storchaka:calliter-stop-exception
Open

gh-64862: Add the stop_exception parameter in iter() and aiter()#156298
serhiy-storchaka wants to merge 4 commits into
python:mainfrom
serhiy-storchaka:calliter-stop-exception

Conversation

@serhiy-storchaka

Copy link
Copy Markdown
Member

iter() and aiter() now accept the keyword-only stop_exception parameter -- an exception class or a tuple of exception classes which ends the iteration:

for item in iter(queue.get_nowait, stop_exception=Empty):
    ...

async for item in aiter(queue.get, stop_exception=QueueShutDown):
    ...

Many callables report exhaustion by raising an exception instead of returning a special value, so the sentinel form cannot be used with them at all.

aiter() also gained the callable form, which it did not have before: the callable is called and its result is awaited for every __anext__() (the callable is only called when the result of __anext__() is awaited).

The second parameter of iter() is now named stop_value and can be passed by keyword. It can be omitted if stop_exception is given.

stop_exception=StopIteration (StopAsyncIteration for aiter()) and an empty tuple never change the behavior, so they are normalized to "no stop exception"; such an iterator is pickled exactly as before. For other cases callable_iterator now has __setstate__(), because the stop exception and the absence of the sentinel cannot be expressed as arguments of iter().

The created iterator stops when the callable raises the specified
exception.  The second parameter of iter() is now named stop_value and
can be passed as a keyword argument.

aiter() now accepts the same stop_value and stop_exception parameters,
calling an asynchronous callable and awaiting the result.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@read-the-docs-community

read-the-docs-community Bot commented Aug 23, 2026

Copy link
Copy Markdown

Documentation build overview

📚 cpython-previews | 🛠️ Build #34202807 | 📁 Comparing 5877437 against main (c1fc445)

  🔍 Preview build  

4 files changed
± library/functions.html
± library/tempfile.html
± whatsnew/3.16.html
± whatsnew/changelog.html

serhiy-storchaka and others added 3 commits August 23, 2026 23:41
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Use StopIteration (StopAsyncIteration for aiter()) as the default instead
of normalizing it to NULL, so that the check is a single
PyErr_ExceptionMatches().

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
If the callable raises StopIteration (StopAsyncIteration in aiter()) which
does not match stop_exception, the consumer would mistake it for the end of
the iteration, or, in the asynchronous case, for the result of the await.
Replace it with RuntimeError, as PEP 479 and PEP 525 do for generators.

StopIteration is therefore no longer special: it stops the iteration only
because it is the default stop_exception.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant