Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

bpo-45250: fix docs regarding __iter__ and iterators being inconsistently required by CPython #29170

Merged
merged 12 commits into from
Nov 20, 2021
14 changes: 7 additions & 7 deletions Doc/c-api/typeobj.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1509,9 +1509,9 @@ and :c:type:`PyType_Type` effectively act as defaults.)

.. c:member:: getiterfunc PyTypeObject.tp_iter

An optional pointer to a function that returns an iterator for the object. Its
presence normally signals that the instances of this type are iterable (although
sequences may be iterable without this function).
An optional pointer to a function that returns an :term:`iterator` for the
object. Its presence normally signals that the instances of this type are
:term:`iterable` (although sequences may be iterable without this function).

This function has the same signature as :c:func:`PyObject_GetIter`::

Expand All @@ -1524,8 +1524,8 @@ and :c:type:`PyType_Type` effectively act as defaults.)

.. c:member:: iternextfunc PyTypeObject.tp_iternext

An optional pointer to a function that returns the next item in an iterator.
The signature is::
An optional pointer to a function that returns the next item in an
:term:`iterator`. The signature is::

PyObject *tp_iternext(PyObject *self);

Expand Down Expand Up @@ -2417,8 +2417,8 @@ Async Object Structures

PyObject *am_await(PyObject *self);

The returned object must be an iterator, i.e. :c:func:`PyIter_Check` must
return ``1`` for it.
The returned object must be an :term:`iterator`, i.e. :c:func:`PyIter_Check`
must return ``1`` for it.

This slot may be set to ``NULL`` if an object is not an :term:`awaitable`.

Expand Down
13 changes: 7 additions & 6 deletions Doc/glossary.rst
Original file line number Diff line number Diff line change
Expand Up @@ -129,8 +129,9 @@ Glossary
:meth:`__aiter__` method. Introduced by :pep:`492`.

asynchronous iterator
An object that implements the :meth:`__aiter__` and :meth:`__anext__`
methods. ``__anext__`` must return an :term:`awaitable` object.
An object that implements the :meth:`__anext__` method (and
implementing :meth:`__aiter__` is strongly encouraged).
``__anext__`` must return an :term:`awaitable` object.
:keyword:`async for` resolves the awaitables returned by an asynchronous
iterator's :meth:`__anext__` method until it raises a
:exc:`StopAsyncIteration` exception. Introduced by :pep:`492`.
Expand Down Expand Up @@ -647,10 +648,10 @@ Glossary
are available a :exc:`StopIteration` exception is raised instead. At this
point, the iterator object is exhausted and any further calls to its
:meth:`__next__` method just raise :exc:`StopIteration` again. Iterators
are required to have an :meth:`__iter__` method that returns the iterator
object itself so every iterator is also iterable and may be used in most
places where other iterables are accepted. One notable exception is code
which attempts multiple iteration passes. A container object (such as a
are strongly encouraged to have an :meth:`__iter__` method that returns
the iterator object itself so an iterator can be used in most places where
other iterables are accepted. One notable exception is code which
attempts multiple iteration passes. A container object (such as a
:class:`list`) produces a fresh new iterator each time you pass it to the
:func:`iter` function or use it in a :keyword:`for` loop. Attempting this
with an iterator will just return the same exhausted iterator object used
brettcannon marked this conversation as resolved.
Show resolved Hide resolved
Expand Down
6 changes: 3 additions & 3 deletions Doc/library/collections.abc.rst
Original file line number Diff line number Diff line change
Expand Up @@ -233,9 +233,9 @@ Collections Abstract Base Classes -- Detailed Descriptions

.. class:: Iterator

ABC for classes that provide the :meth:`~iterator.__iter__` and
:meth:`~iterator.__next__` methods. See also the definition of
:term:`iterator`.
ABC for classes that provide the :meth:`~iterator.__next__` method. The ABC
also provides an implementation of :meth:`~iterator.__iter__` for
convenience.See also the definition of :term:`iterator`.
brettcannon marked this conversation as resolved.
Show resolved Hide resolved

.. class:: Reversible

Expand Down
9 changes: 3 additions & 6 deletions Doc/library/functions.rst
Original file line number Diff line number Diff line change
Expand Up @@ -66,9 +66,6 @@ are always available. They are listed here in alphabetical order.
Return an :term:`asynchronous iterator` for an :term:`asynchronous iterable`.
Equivalent to calling ``x.__aiter__()``.

``aiter(x)`` itself has an ``__aiter__()`` method that returns ``x``,
so ``aiter(aiter(x))`` is the same as ``aiter(x)``.

Note: Unlike :func:`iter`, :func:`aiter` has no 2-argument variant.

.. versionadded:: 3.10
Expand Down Expand Up @@ -929,8 +926,8 @@ are always available. They are listed here in alphabetical order.
Return an :term:`iterator` object. The first argument is interpreted very
differently depending on the presence of the second argument. Without a
second argument, *object* must be a collection object which supports the
iteration protocol (the :meth:`__iter__` method), or it must support the
sequence protocol (the :meth:`__getitem__` method with integer arguments
:term:`iterable` protocol (the :meth:`__iter__` method), or it must support
the sequence protocol (the :meth:`__getitem__` method with integer arguments
starting at ``0``). If it does not support either of those protocols,
:exc:`TypeError` is raised. If the second argument, *sentinel*, is given,
then *object* must be a callable object. The iterator created in this case
Expand Down Expand Up @@ -1060,7 +1057,7 @@ are always available. They are listed here in alphabetical order.

.. function:: next(iterator[, default])

Retrieve the next item from the *iterator* by calling its
Retrieve the next item from the :term:`iterator` by calling its
:meth:`~iterator.__next__` method. If *default* is given, it is returned
if the iterator is exhausted, otherwise :exc:`StopIteration` is raised.

Expand Down
34 changes: 13 additions & 21 deletions Doc/library/stdtypes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -811,39 +811,31 @@ support iteration. Sequences, described below in more detail, always support
the iteration methods.

One method needs to be defined for container objects to provide iteration
support:
support and be considered an :term:`iterable`:

.. XXX duplicated in reference/datamodel!

.. method:: container.__iter__()

Return an iterator object. The object is required to support the iterator
protocol described below. If a container supports different types of
iteration, additional methods can be provided to specifically request
Return an :term:`iterator` object. The object is required to support the
iterator protocol described below. If a container supports different types
of iteration, additional methods can be provided to specifically request
iterators for those iteration types. (An example of an object supporting
multiple forms of iteration would be a tree structure which supports both
breadth-first and depth-first traversal.) This method corresponds to the
:c:member:`~PyTypeObject.tp_iter` slot of the type structure for Python objects in the Python/C
API.

The iterator objects themselves are required to support the following two
methods, which together form the :dfn:`iterator protocol`:


.. method:: iterator.__iter__()

Return the iterator object itself. This is required to allow both containers
and iterators to be used with the :keyword:`for` and :keyword:`in` statements.
This method corresponds to the :c:member:`~PyTypeObject.tp_iter` slot of the type structure for
Python objects in the Python/C API.
:c:member:`~PyTypeObject.tp_iter` slot of the type structure for Python
objects in the Python/C API.

The iterator objects themselves are required to support the following the
brettcannon marked this conversation as resolved.
Show resolved Hide resolved
method, which forms the :dfn:`iterator protocol` (although iterators are
strongly encouraged to also implement :meth:`__iter__` as well):

.. method:: iterator.__next__()

Return the next item from the container. If there are no further items, raise
the :exc:`StopIteration` exception. This method corresponds to the
:c:member:`~PyTypeObject.tp_iternext` slot of the type structure for Python objects in the
Python/C API.
Return the next item from the container. If there are no further items,
raise the :exc:`StopIteration` exception. This method corresponds to the
:c:member:`~PyTypeObject.tp_iternext` slot of the type structure for Python
objects in the Python/C API.

Python defines several iterator objects to support iteration over general and
specific sequence types, dictionaries, and other more specialized forms. The
Expand Down
28 changes: 15 additions & 13 deletions Doc/reference/datamodel.rst
Original file line number Diff line number Diff line change
Expand Up @@ -648,13 +648,13 @@ Callable types

A function or method which uses the :keyword:`yield` statement (see section
:ref:`yield`) is called a :dfn:`generator function`. Such a function, when
called, always returns an iterator object which can be used to execute the
body of the function: calling the iterator's :meth:`iterator.__next__`
method will cause the function to execute until it provides a value
using the :keyword:`!yield` statement. When the function executes a
:keyword:`return` statement or falls off the end, a :exc:`StopIteration`
exception is raised and the iterator will have reached the end of the set of
values to be returned.
called, always returns an :term:`iterator` object which can be used to
execute the body of the function: calling the iterator's
:meth:`iterator.__next__` method will cause the function to execute until
it provides a value using the :keyword:`!yield` statement. When the
function executes a :keyword:`return` statement or falls off the end, a
:exc:`StopIteration` exception is raised and the iterator will have
reached the end of the set of values to be returned.

Coroutine functions
.. index::
Expand All @@ -674,7 +674,7 @@ Callable types
A function or method which is defined using :keyword:`async def` and
which uses the :keyword:`yield` statement is called a
:dfn:`asynchronous generator function`. Such a function, when called,
returns an asynchronous iterator object which can be used in an
returns an :term:`asynchronous iterator` object which can be used in an
:keyword:`async for` statement to execute the body of the function.

Calling the asynchronous iterator's :meth:`aiterator.__anext__` method
Expand Down Expand Up @@ -2371,12 +2371,14 @@ through the object's keys; for sequences, it should iterate through the values.

.. method:: object.__iter__(self)

This method is called when an iterator is required for a container. This method
should return a new iterator object that can iterate over all the objects in the
container. For mappings, it should iterate over the keys of the container.
This method is called when an :term:`iterator` is required for a container.
This method should return a new iterator object that can iterate over all the
objects in the container. For mappings, it should iterate over the keys of
the container.

Iterator objects also need to implement this method; they are required to return
themselves. For more information on iterator objects, see :ref:`typeiter`.
Iterator objects also need to implement this method; they are required to
return themselves. For more information on iterator objects, see
:ref:`typeiter`.


.. method:: object.__reversed__(self)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Update the documentation to correctly reflect that iterators only need to
define ``__next__`` and not ``__iter__``, ``__anext__`` and not
``__anext__`` for asynchronous iterators.
brettcannon marked this conversation as resolved.
Show resolved Hide resolved