PEP 828 – Supporting ‘yield from’ in asynchronous generators | peps.python.org
Following system colour scheme
Selected dark colour scheme
Selected light colour scheme
PEP 828 – Supporting ‘yield from’ in asynchronous generators
PEP 828 – Supporting ‘yield from’ in asynchronous generators
Author:<br>Peter Bierma<br>PEP-Delegate:<br>Yury Selivanov<br>Discussions-To:<br>Discourse thread<br>Status:<br>Accepted<br>Type:<br>Standards Track<br>Created:<br>07-Mar-2026<br>Python-Version:<br>3.16<br>Post-History:<br>07-Mar-2026,<br>09-Mar-2026<br>Resolution:<br>03-Aug-2026
Table of Contents<br>Abstract
Terminology
Motivation<br>Implementation complexity has gone down
Symmetry with synchronous generators
Subgenerator delegation is useful for asynchronous generators
Specification<br>Compiler changes
Changes to StopAsyncIteration
return statements inside asynchronous generators
yield from semantics in an asynchronous generator
Rationale<br>Relation to synchronous generators
Choice of yield from as the syntax
Backwards Compatibility
Security Implications
How to Teach This
Reference Implementation
Rejected Ideas<br>Using async yield from as the syntax<br>async from, await from, and similar spellings
Allowing delegation to synchronous subgenerators
Acknowledgements
Change History
Copyright
Abstract
This PEP introduces support for yield from in an<br>asynchronous generator function:
async def agenerator():<br>yield 1<br>yield 2<br>return 3
async def main():<br>result = yield from agenerator()<br>assert result == 3
Terminology
This PEP refers to an async def function that contains a yield<br>as an asynchronous generator, sometimes suffixed with “function”.<br>This is not to be confused with an asynchronous generator iterator,<br>which is the object returned by an asynchronous generator.
This PEP also uses the term “subgenerator” to refer to a generator, synchronous<br>or asynchronous, that is used inside a yield from.
Motivation
Implementation complexity has gone down
Historically, yield from was not added to asynchronous generators due to<br>concerns about the complexity of the implementation. To quote PEP 525:
While it is theoretically possible to implement yield from support for<br>asynchronous generators, it would require a serious redesign of the<br>generators implementation.
As of March 2026, the author of this proposal does not believe this to be true<br>given the current state of CPython’s asynchronous generator implementation.<br>This proposal comes with a reference implementation to argue this point, but<br>it is acknowledged that complexity is often subjective.
Symmetry with synchronous generators
yield from was added to synchronous generators in PEP 380 because<br>delegation to another generator is a useful thing to do. Due to the<br>aforementioned complexity in CPython’s generator implementation, PEP 525<br>omitted support for yield from in asynchronous generators, but this has<br>left a gap in the language.
This gap has not gone unnoticed by users. There have been three separate<br>requests for yield from or return behavior (which are closely related)<br>in asynchronous generators:
https://discuss.python.org/t/8897
https://discuss.python.org/t/47050
https://discuss.python.org/t/66886
Additionally, users have questioned<br>this design decision on Stack Overflow.
Subgenerator delegation is useful for asynchronous generators
The current workaround for the lack of yield from support in asynchronous<br>generators is to use a for/async for loop that manually yields each<br>item. This comes with a few drawbacks:
It obscures the intent of the code and increases the amount of effort<br>necessary to work with asynchronous generators, because each delegation<br>point becomes a loop. This damages the power of asynchronous generators.
asend(), athrow(), and aclose()<br>do not interact properly with the caller. This is the primary reason that<br>yield from was added in the first place.
Return values are not natively supported with asynchronous generators. The<br>workaround for this is to raise an exception, which increases boilerplate.
Specification
Compiler changes
The compiler will no longer emit a SyntaxError for<br>return or yield from statements inside asynchronous generators.
Changes to StopAsyncIteration
The StopAsyncIteration exception will gain a new value attribute<br>to be used as the result of yield from expressions in asynchronous generators.
This attribute can be supplied by passing a positional argument to<br>StopAsyncIteration. For example:
>>> exception = StopAsyncIteration(42)<br>>>> exception.value<br>42
If no argument is supplied, value will be None.
return statements inside asynchronous generators
In the body of an asynchronous generator function, the statement<br>return expression is roughly equivalent to<br>raise StopAsyncIteration(expression). However, similar to implicit<br>StopIteration exceptions raised inside synchronous generators,<br>the exception cannot be caught in the body of the asynchronous generator.
yield from semantics in an asynchronous generator
In an asynchronous generator, the statement
RESULT = yield...