From 6d411c6ce4286b21948e1d7df182f510cd9857b2 Mon Sep 17 00:00:00 2001 From: Antti Haapala Date: Wed, 19 Jul 2017 14:36:31 +0300 Subject: [PATCH 1/4] Fix the eq check that is used in absence of `__contains__` Both the `__iter__` and the index-iteration method test the `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`. ```>>> x = float('nan') >>> x == x False >>> x is x True >>> class Foo: ... def __iter__(self): ... return iter([x]) ... >>> x in Foo() True >>> any(x == i for i in Foo()) False >>> class Bar: ... def __getitem__(self): ... return [x].__getitem__(self) ... >>> class Bar: ... def __getitem__(self, i): ... return [x].__getitem__(i) ... >>> x in Bar Traceback (most recent call last): File "", line 1, in TypeError: argument of type 'type' is not iterable >>> x in Bar() True >>> any(x == i for i in Bar()) False``` --- Doc/reference/expressions.rst | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/Doc/reference/expressions.rst b/Doc/reference/expressions.rst index ddcbd5567c1ee9..5e06cf4af9922a 100644 --- a/Doc/reference/expressions.rst +++ b/Doc/reference/expressions.rst @@ -1443,14 +1443,15 @@ y`` returns ``True`` if ``y.__contains__(x)`` returns a true value, and ``False`` otherwise. For user-defined classes which do not define :meth:`__contains__` but do define -:meth:`__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 :keyword:`in` raised that exception. +:meth:`__iter__`, ``x in y`` is ``True`` if some value ``z``, for which the +expression``x is z or x == z`` is True, is produced while iterating over ``y``. +If an exception is raised during the iteration, it is as if :keyword:`in` raised +that exception. Lastly, the old-style iteration protocol is tried: if a class defines :meth:`__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 :exc:`IndexError` exception. (If any other exception is raised, it is as +integer index *i* such that ``x is y[i] or x == y[i]``, and no lower integer index +raises the :exc:`IndexError` exception. (If any other exception is raised, it is as if :keyword:`in` raised that exception). .. index:: From 29abde02d45c8ac4c3e9e4645e84ccdeed8a601a Mon Sep 17 00:00:00 2001 From: Antti Haapala Date: Wed, 19 Jul 2017 15:01:08 +0300 Subject: [PATCH 2/4] lowercase the true, as it need not be `True`. --- Doc/reference/expressions.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/reference/expressions.rst b/Doc/reference/expressions.rst index 5e06cf4af9922a..05bbdc660c7f56 100644 --- a/Doc/reference/expressions.rst +++ b/Doc/reference/expressions.rst @@ -1444,7 +1444,7 @@ y`` returns ``True`` if ``y.__contains__(x)`` returns a true value, and For user-defined classes which do not define :meth:`__contains__` but do define :meth:`__iter__`, ``x in y`` is ``True`` if some value ``z``, for which the -expression``x is z or x == z`` is True, is produced while iterating over ``y``. +expression``x is z or x == z`` is true, is produced while iterating over ``y``. If an exception is raised during the iteration, it is as if :keyword:`in` raised that exception. From 511406d75f24aa35dba8a1feb3c846a0d9b113ff Mon Sep 17 00:00:00 2001 From: Antti Haapala Date: Wed, 19 Jul 2017 15:02:11 +0300 Subject: [PATCH 3/4] Add the missing space here. --- Doc/reference/expressions.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/reference/expressions.rst b/Doc/reference/expressions.rst index 05bbdc660c7f56..47767d1e0096c8 100644 --- a/Doc/reference/expressions.rst +++ b/Doc/reference/expressions.rst @@ -1444,7 +1444,7 @@ y`` returns ``True`` if ``y.__contains__(x)`` returns a true value, and For user-defined classes which do not define :meth:`__contains__` but do define :meth:`__iter__`, ``x in y`` is ``True`` if some value ``z``, for which the -expression``x is z or x == z`` is true, is produced while iterating over ``y``. +expression ``x is z or x == z`` is true, is produced while iterating over ``y``. If an exception is raised during the iteration, it is as if :keyword:`in` raised that exception. From b4f285f984545eac6f141ff40fb27b97c9acc926 Mon Sep 17 00:00:00 2001 From: Cheryl Sabella Date: Thu, 30 May 2019 16:09:47 -0400 Subject: [PATCH 4/4] Fix trailing whitespace --- Doc/reference/expressions.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Doc/reference/expressions.rst b/Doc/reference/expressions.rst index 47767d1e0096c8..d7b6e6eb7a46e8 100644 --- a/Doc/reference/expressions.rst +++ b/Doc/reference/expressions.rst @@ -1443,9 +1443,9 @@ y`` returns ``True`` if ``y.__contains__(x)`` returns a true value, and ``False`` otherwise. For user-defined classes which do not define :meth:`__contains__` but do define -:meth:`__iter__`, ``x in y`` is ``True`` if some value ``z``, for which the -expression ``x is z or x == z`` is true, is produced while iterating over ``y``. -If an exception is raised during the iteration, it is as if :keyword:`in` raised +:meth:`__iter__`, ``x in y`` is ``True`` if some value ``z``, for which the +expression ``x is z or x == z`` is true, is produced while iterating over ``y``. +If an exception is raised during the iteration, it is as if :keyword:`in` raised that exception. Lastly, the old-style iteration protocol is tried: if a class defines