Skip to content

Commit 99aad31

Browse files
authored
[3.10] bpo-45250: fix docs regarding __iter__ and iterators being inconsistently required by CPython (GH-29170) (GH-29650)
It is now considered a historical accident that e.g. `for` loops and the `iter()` built-in function do not require the iterators they work with to define `__iter__`, only `__next__`. (cherry picked from commit be36e06) Co-authored-by: Brett Cannon <[email protected]>
1 parent 56b5cd5 commit 99aad31

File tree

7 files changed

+51
-47
lines changed

7 files changed

+51
-47
lines changed

Doc/c-api/iter.rst

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@ There are two functions specifically for working with iterators.
99

1010
.. c:function:: int PyIter_Check(PyObject *o)
1111
12-
Return non-zero if the object *o* supports the iterator protocol, and ``0``
13-
otherwise. This function always succeeds.
12+
Return non-zero if the object *o* can be safely passed to
13+
:c:func:`PyIter_Next`, and ``0`` otherwise. This function always succeeds.
1414
1515
.. c:function:: int PyAIter_Check(PyObject *o)
1616
@@ -21,10 +21,11 @@ There are two functions specifically for working with iterators.
2121
2222
.. c:function:: PyObject* PyIter_Next(PyObject *o)
2323
24-
Return the next value from the iteration *o*. The object must be an iterator
25-
(it is up to the caller to check this). If there are no remaining values,
26-
returns ``NULL`` with no exception set. If an error occurs while retrieving
27-
the item, returns ``NULL`` and passes along the exception.
24+
Return the next value from the iterator *o*. The object must be an iterator
25+
according to :c:func:`PyIter_Check` (it is up to the caller to check this).
26+
If there are no remaining values, returns ``NULL`` with no exception set.
27+
If an error occurs while retrieving the item, returns ``NULL`` and passes
28+
along the exception.
2829
2930
To write a loop which iterates over an iterator, the C code should look
3031
something like this::

Doc/c-api/typeobj.rst

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1520,9 +1520,9 @@ and :c:type:`PyType_Type` effectively act as defaults.)
15201520

15211521
.. c:member:: getiterfunc PyTypeObject.tp_iter
15221522
1523-
An optional pointer to a function that returns an iterator for the object. Its
1524-
presence normally signals that the instances of this type are iterable (although
1525-
sequences may be iterable without this function).
1523+
An optional pointer to a function that returns an :term:`iterator` for the
1524+
object. Its presence normally signals that the instances of this type are
1525+
:term:`iterable` (although sequences may be iterable without this function).
15261526

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

@@ -1535,8 +1535,8 @@ and :c:type:`PyType_Type` effectively act as defaults.)
15351535

15361536
.. c:member:: iternextfunc PyTypeObject.tp_iternext
15371537
1538-
An optional pointer to a function that returns the next item in an iterator.
1539-
The signature is::
1538+
An optional pointer to a function that returns the next item in an
1539+
:term:`iterator`. The signature is::
15401540

15411541
PyObject *tp_iternext(PyObject *self);
15421542

@@ -2428,8 +2428,8 @@ Async Object Structures
24282428

24292429
PyObject *am_await(PyObject *self);
24302430

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

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

Doc/glossary.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -669,6 +669,11 @@ Glossary
669669

670670
More information can be found in :ref:`typeiter`.
671671

672+
.. impl-detail::
673+
674+
CPython does not consistently apply the requirement that an iterator
675+
define :meth:`__iter__`.
676+
672677
key function
673678
A key function or collation function is a callable that returns a value
674679
used for sorting or ordering. For example, :func:`locale.strxfrm` is

Doc/library/functions.rst

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -66,9 +66,6 @@ are always available. They are listed here in alphabetical order.
6666
Return an :term:`asynchronous iterator` for an :term:`asynchronous iterable`.
6767
Equivalent to calling ``x.__aiter__()``.
6868

69-
``aiter(x)`` itself has an ``__aiter__()`` method that returns ``x``,
70-
so ``aiter(aiter(x))`` is the same as ``aiter(x)``.
71-
7269
Note: Unlike :func:`iter`, :func:`aiter` has no 2-argument variant.
7370

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

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

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

Doc/library/stdtypes.rst

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -772,40 +772,41 @@ using two distinct methods; these are used to allow user-defined classes to
772772
support iteration. Sequences, described below in more detail, always support
773773
the iteration methods.
774774

775-
One method needs to be defined for container objects to provide iteration
775+
One method needs to be defined for container objects to provide :term:`iterable`
776776
support:
777777

778778
.. XXX duplicated in reference/datamodel!
779779
780780
.. method:: container.__iter__()
781781

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

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

794794

795795
.. method:: iterator.__iter__()
796796

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

802803

803804
.. method:: iterator.__next__()
804805

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

810811
Python defines several iterator objects to support iteration over general and
811812
specific sequence types, dictionaries, and other more specialized forms. The

Doc/reference/datamodel.rst

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -648,13 +648,13 @@ Callable types
648648

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

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

680680
Calling the asynchronous iterator's :meth:`aiterator.__anext__` method
@@ -2464,12 +2464,10 @@ through the object's keys; for sequences, it should iterate through the values.
24642464

24652465
.. method:: object.__iter__(self)
24662466

2467-
This method is called when an iterator is required for a container. This method
2468-
should return a new iterator object that can iterate over all the objects in the
2469-
container. For mappings, it should iterate over the keys of the container.
2470-
2471-
Iterator objects also need to implement this method; they are required to return
2472-
themselves. For more information on iterator objects, see :ref:`typeiter`.
2467+
This method is called when an :term:`iterator` is required for a container.
2468+
This method should return a new iterator object that can iterate over all the
2469+
objects in the container. For mappings, it should iterate over the keys of
2470+
the container.
24732471

24742472

24752473
.. method:: object.__reversed__(self)
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Update the documentation to note that CPython does not consistently
2+
require iterators to define ``__iter__``.

0 commit comments

Comments
 (0)