Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions Doc/c-api/frame.rst
Original file line number Diff line number Diff line change
Expand Up @@ -99,8 +99,6 @@ See also :ref:`Reflection <reflection>`.

Get the *frame*'s :attr:`~frame.f_lasti` attribute.

Returns -1 if ``frame.f_lasti`` is ``None``.

.. versionadded:: 3.11


Expand Down
2 changes: 1 addition & 1 deletion Doc/c-api/gcsupport.rst
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ rules:
.. warning::
If a type adds the Py_TPFLAGS_HAVE_GC, then it *must* implement at least
a :c:member:`~PyTypeObject.tp_traverse` handler or explicitly use one
from its subclass or subclasses.
from a base class.

When calling :c:func:`PyType_Ready` or some of the APIs that indirectly
call it like :c:func:`PyType_FromSpecWithBases` or
Expand Down
4 changes: 2 additions & 2 deletions Doc/c-api/gen.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ Generator Objects
-----------------

Generator objects are what Python uses to implement generator iterators. They
are normally created by iterating over a function that yields values, rather
than explicitly calling :c:func:`PyGen_New` or :c:func:`PyGen_NewWithQualName`.
are normally created by calling a generator function, rather than explicitly
calling :c:func:`PyGen_New` or :c:func:`PyGen_NewWithQualName`.


.. c:type:: PyGenObject
Expand Down
2 changes: 1 addition & 1 deletion Doc/c-api/object.rst
Original file line number Diff line number Diff line change
Expand Up @@ -423,7 +423,7 @@ Object Protocol
If *cls* has a :meth:`~type.__subclasscheck__` method, it will be called to
determine the subclass status as described in :pep:`3119`. Otherwise,
*derived* is a subclass of *cls* if it is a direct or indirect subclass,
i.e. contained in :attr:`cls.__mro__ <type.__mro__>`.
i.e. if *cls* is contained in :attr:`derived.__mro__ <type.__mro__>`.

Normally only class objects, i.e. instances of :class:`type` or a derived
class, are considered classes. However, objects can override this by having
Expand Down
2 changes: 1 addition & 1 deletion Doc/c-api/typeobj.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2527,7 +2527,7 @@ and :c:data:`PyType_Type` effectively act as defaults.)

Specifically, if *type* uses the default metaclass,
``type->tp_vectorcall`` must behave the same as
:c:expr:`PyType_Type->tp_call`, which:
``Py_TYPE(type)->tp_call``, which:

- calls ``type->tp_new``,

Expand Down
2 changes: 1 addition & 1 deletion Doc/howto/descriptor.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1754,7 +1754,7 @@ At this point, the metaclass has loaded member objects for *x* and *y*::
>>> isinstance(vars(H)['y'], Member)
True

When instances are created, they have a ``slot_values`` list where the
When instances are created, they have a ``_slotvalues`` list where the
attributes are stored:

.. doctest::
Expand Down
2 changes: 1 addition & 1 deletion Doc/howto/enum.rst
Original file line number Diff line number Diff line change
Expand Up @@ -913,7 +913,7 @@ Some rules:
:class:`~dataclasses.dataclass`
6. %-style formatting: ``%s`` and ``%r`` call the :class:`Enum` class's
:meth:`~object.__str__` and :meth:`~object.__repr__` respectively; other codes (such as
``%i`` or ``%h`` for IntEnum) treat the enum member as its mixed-in type.
``%i`` or ``%x`` for IntEnum) treat the enum member as its mixed-in type.
7. :ref:`Formatted string literals <f-strings>`, :meth:`str.format`,
and :func:`format` will use the enum's :meth:`~object.__str__` method.

Expand Down
2 changes: 1 addition & 1 deletion Doc/howto/isolating-extensions.rst
Original file line number Diff line number Diff line change
Expand Up @@ -530,7 +530,7 @@ and the corresponding :c:type:`PyCMethod` signature::
PyTypeObject *defining_class, // defining class
PyObject *const *args, // C array of arguments
Py_ssize_t nargs, // length of "args"
PyObject *kwnames) // NULL, or dict of keyword arguments
PyObject *kwnames) // NULL, or tuple of keyword argument names

Once you have the defining class, call :c:func:`PyType_GetModuleState` to get
the state of its associated module.
Expand Down
2 changes: 1 addition & 1 deletion Doc/howto/perf_profiling.rst
Original file line number Diff line number Diff line change
Expand Up @@ -273,7 +273,7 @@ or using the environment variable::

``perf inject --jit`` command will read ``perf.data``,
automatically pick up the perf dump file that Python creates (in
``/tmp/perf-$PID.dump``), and then create ``perf.jit.data`` which merges all the
``/tmp/jit-$PID.dump``), and then create ``perf.jit.data`` which merges all the
JIT information together. It should also create a lot of ``jitted-XXXX-N.so``
files in the current directory which are ELF images for all the JIT trampolines
that were created by Python.
Expand Down
2 changes: 1 addition & 1 deletion Doc/howto/remote_debugging.rst
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ necessary entitlement and add it to the Python binary:
codesign --sign - --entitlements get-task-allow.plist path/to/bin/python3

where ``path/to/bin/python3`` is the path to your Python binary, which you can
find by e.g. running ``which python3`` or evaluating ``sys.base_executable`` at
find by e.g. running ``which python3`` or evaluating ``sys._base_executable`` at
the Python REPL. (These instructions are for a non-framework build of Python.
Framework builds may need to be configured differently.)

Expand Down
2 changes: 1 addition & 1 deletion Doc/library/bz2.rst
Original file line number Diff line number Diff line change
Expand Up @@ -277,7 +277,7 @@ Incremental (de)compression
.. attribute:: needs_input

``False`` if the :meth:`.decompress` method can provide more
decompressed data before requiring new uncompressed input.
decompressed data before requiring new compressed input.

.. versionadded:: 3.5

Expand Down
2 changes: 1 addition & 1 deletion Doc/library/dis.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1299,7 +1299,7 @@ iterations of the loop.
* the global ``super``

With respect to its argument, it works similarly to :opcode:`LOAD_ATTR`,
except that ``namei`` is shifted left by 2 bits instead of 1.
except that ``namei`` is shifted right by 2 bits instead of 1.

The low bit of ``namei`` signals to attempt a method load, as with
:opcode:`LOAD_ATTR`, which results in pushing ``NULL`` and the loaded method.
Expand Down
2 changes: 1 addition & 1 deletion Doc/library/sys.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2061,7 +2061,7 @@ always available. Unless explicitly noted otherwise, all variables are read-only
.. versionadded:: 3.6
See :pep:`525` for more details, and for a reference example of a
*finalizer* method see the implementation of
``asyncio.Loop.shutdown_asyncgens`` in
``asyncio.BaseEventLoop._asyncgen_finalizer_hook`` in
:source:`Lib/asyncio/base_events.py`

.. note::
Expand Down
8 changes: 4 additions & 4 deletions Doc/library/textwrap.rst
Original file line number Diff line number Diff line change
Expand Up @@ -250,10 +250,10 @@ hyphenated words; only then will long words be broken if necessary, unless

:attr:`fix_sentence_endings` is false by default.

Since the sentence detection algorithm relies on ``string.lowercase`` for
the definition of "lowercase letter", and a convention of using two spaces
after a period to separate sentences on the same line, it is specific to
English-language texts.
Since the sentence detection algorithm defines "lowercase letter" using
the characters in ``string.ascii_lowercase``, and relies on a convention
of using two spaces after a period to separate sentences on the same line,
it is specific to English-language texts.


.. attribute:: break_long_words
Expand Down
25 changes: 12 additions & 13 deletions Doc/reference/expressions.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1249,8 +1249,7 @@ If an asynchronous generator happens to exit early by :keyword:`break`, the call
task being cancelled, or other exceptions, the generator's async cleanup code
will run and possibly raise exceptions or access context variables in an
unexpected context--perhaps after the lifetime of tasks it depends, or
during the event loop shutdown when the async-generator garbage collection hook
is called.
during the event loop shutdown.
To prevent this, the caller must explicitly close the async generator by calling
:meth:`~agen.aclose` method to finalize the generator and ultimately detach it
from the event loop.
Expand All @@ -1263,17 +1262,17 @@ construct could result in a failure to execute pending :keyword:`finally`
clauses. In this case, it is the responsibility of the event loop or
scheduler running the asynchronous generator to call the asynchronous
generator-iterator's :meth:`~agen.aclose` method and run the resulting
coroutine object, thus allowing any pending :keyword:`!finally` clauses
to execute.

To take care of finalization upon event loop termination, an event loop should
define a *finalizer* function which takes an asynchronous generator-iterator and
presumably calls :meth:`~agen.aclose` and executes the coroutine.
This *finalizer* may be registered by calling :func:`sys.set_asyncgen_hooks`.
When first iterated over, an asynchronous generator-iterator will store the
registered *finalizer* to be called upon finalization. For a reference example
of a *finalizer* method see the implementation of
``asyncio.Loop.shutdown_asyncgens`` in :source:`Lib/asyncio/base_events.py`.
awaitable, thus allowing any pending :keyword:`!finally` clauses to execute.

To handle finalization when an asynchronous generator is about to be garbage
collected, an event loop should define a *finalizer* function which takes an
asynchronous generator-iterator and schedules the awaitable returned by
:meth:`~agen.aclose`. This *finalizer* may be registered by calling
:func:`sys.set_asyncgen_hooks`. When first iterated over, an asynchronous
generator-iterator will store the registered *finalizer* to be called upon
finalization. For a reference example of a *finalizer* method see the
implementation of ``asyncio.BaseEventLoop._asyncgen_finalizer_hook`` in
:source:`Lib/asyncio/base_events.py`.

@methane methane Nov 2, 2026 •

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@1st1 @asvetlov would you review this part of change?

The documentation conflates async generator finalization during garbage collection with event loop shutdown. The finalizer registered with sys.set_asyncgen_hooks() is called when a generator is about to be garbage collected, while loop.shutdown_asyncgens() explicitly closes the generators tracked by the loop. This change clarifies that distinction and references _asyncgen_finalizer_hook() as the correct callback example.


The expression ``yield from <expr>`` is a syntax error when used in an
asynchronous generator function.
Expand Down
Loading