Skip to content

Commit bb6a694

Browse files
committed
Docs: clarify asynchronous generator finalization
1 parent d7e65b4 commit bb6a694

2 files changed

Lines changed: 12 additions & 14 deletions

File tree

‎Doc/library/sys.rst‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2061,7 +2061,7 @@ always available. Unless explicitly noted otherwise, all variables are read-only
20612061
.. versionadded:: 3.6
20622062
See :pep:`525` for more details, and for a reference example of a
20632063
*finalizer* method see the implementation of
2064-
``asyncio.Loop.shutdown_asyncgens`` in
2064+
``asyncio.BaseEventLoop._asyncgen_finalizer_hook`` in
20652065
:source:`Lib/asyncio/base_events.py`
20662066

20672067
.. note::

‎Doc/reference/expressions.rst‎

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1249,8 +1249,7 @@ If an asynchronous generator happens to exit early by :keyword:`break`, the call
12491249
task being cancelled, or other exceptions, the generator's async cleanup code
12501250
will run and possibly raise exceptions or access context variables in an
12511251
unexpected context--perhaps after the lifetime of tasks it depends, or
1252-
during the event loop shutdown when the async-generator garbage collection hook
1253-
is called.
1252+
during the event loop shutdown.
12541253
To prevent this, the caller must explicitly close the async generator by calling
12551254
:meth:`~agen.aclose` method to finalize the generator and ultimately detach it
12561255
from the event loop.
@@ -1263,17 +1262,16 @@ construct could result in a failure to execute pending :keyword:`finally`
12631262
clauses. In this case, it is the responsibility of the event loop or
12641263
scheduler running the asynchronous generator to call the asynchronous
12651264
generator-iterator's :meth:`~agen.aclose` method and run the resulting
1266-
coroutine object, thus allowing any pending :keyword:`!finally` clauses
1267-
to execute.
1268-
1269-
To take care of finalization upon event loop termination, an event loop should
1270-
define a *finalizer* function which takes an asynchronous generator-iterator and
1271-
presumably calls :meth:`~agen.aclose` and executes the coroutine.
1272-
This *finalizer* may be registered by calling :func:`sys.set_asyncgen_hooks`.
1273-
When first iterated over, an asynchronous generator-iterator will store the
1274-
registered *finalizer* to be called upon finalization. For a reference example
1275-
of a *finalizer* method see the implementation of
1276-
``asyncio.BaseEventLoop.shutdown_asyncgens`` in
1265+
awaitable, thus allowing any pending :keyword:`!finally` clauses to execute.
1266+
1267+
To handle finalization when an asynchronous generator is about to be garbage
1268+
collected, an event loop should define a *finalizer* function which takes an
1269+
asynchronous generator-iterator and schedules the awaitable returned by
1270+
:meth:`~agen.aclose`. This *finalizer* may be registered by calling
1271+
:func:`sys.set_asyncgen_hooks`. When first iterated over, an asynchronous
1272+
generator-iterator will store the registered *finalizer* to be called upon
1273+
finalization. For a reference example of a *finalizer* method see the
1274+
implementation of ``asyncio.BaseEventLoop._asyncgen_finalizer_hook`` in
12771275
:source:`Lib/asyncio/base_events.py`.
12781276

12791277
The expression ``yield from <expr>`` is a syntax error when used in an

0 commit comments

Comments
 (0)