Issue 30969: Docs should say that x is z or x == z
is used for x in y
in containers that do not implement __contains__
(original) (raw)
The doc reference/expressions.srt says that
For user-defined classes which do not define contains() but do define iter(), x in y is True if some value z with x == z is produced while iterating over y. If an exception is raised during the iteration, it is as if in raised that exception.
and
Lastly, the old-style iteration protocol is tried: if a class defines getitem(), x in y is True if and only if there is a non-negative integer index i such that x == y[i], and all lower integer indices do not raise IndexError exception. (If any other exception is raised, it is as if in raised that exception).
The documentation doesn't match the implementation, which clearly does x is y or x == y
to check if x
is the element y
from a container. Both the __iter__
and the index-iteration method test the elements using is
first. While the document says that x is x
means that x == x
should be true, it is not true for example in the case of nan
:
I think you change is appropriate given that the "equivalent to" for the built in iterators contains the 'is' expression.
However, I also think we should drop that second whole paragraph, and in the previous paragraph say "...but are :term:iterable
...". Because conceptually what we do is iterate whatever we're given if iter doesn't return a TypeError, and it is iter that handles the fallback to the older getitem protocol. I don't see why we should re-explain the iteration protocol in the docs for 'in'. (I haven't looked at how this is actually implemented, but the implementation ought to be equivalent to that or we will eventually run into bugs.) I don't think this would result in any loss of precision or understandability, and in fact I think it would make it easier to understand.
See also issue 27605, which also wants to edit this section slightly.