diff options
author | Miss Islington (bot) <31488909+miss-islington@users.noreply.github.com> | 2020-06-22 08:21:04 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-06-22 08:21:04 (GMT) |
commit | b99824a8e14d94c3c5c29499a08fe70deb477d0c (patch) | |
tree | 2071b90c828dccc80d65b6b280197d97b9162c9f | |
parent | d5ee9b9940ba24120838b07061058afe931cfff1 (diff) | |
download | cpython-b99824a8e14d94c3c5c29499a08fe70deb477d0c.zip cpython-b99824a8e14d94c3c5c29499a08fe70deb477d0c.tar.gz cpython-b99824a8e14d94c3c5c29499a08fe70deb477d0c.tar.bz2 |
bpo-40824: Do not mask errors in __iter__ in "in" and the operator module. (GH-20537)
Unexpected errors in calling the __iter__ method are no longer
masked by TypeError in the "in" operator and functions
operator.contains(), operator.indexOf() and operator.countOf().
(cherry picked from commit cafe1b6e9d3594a34aba50e872d4198296ffaadf)
Co-authored-by: Serhiy Storchaka <storchaka@gmail.com>
-rw-r--r-- | Lib/test/test_iter.py | 7 | ||||
-rw-r--r-- | Lib/test/test_operator.py | 7 | ||||
-rw-r--r-- | Misc/NEWS.d/next/Core and Builtins/2020-05-30-14-37-18.bpo-40824.XR3V5s.rst | 4 | ||||
-rw-r--r-- | Objects/abstract.c | 4 |
4 files changed, 21 insertions, 1 deletions
diff --git a/Lib/test/test_iter.py b/Lib/test/test_iter.py index 542b284..22553d5 100644 --- a/Lib/test/test_iter.py +++ b/Lib/test/test_iter.py @@ -62,6 +62,10 @@ class NoIterClass: return i __iter__ = None +class BadIterableClass: + def __iter__(self): + raise ZeroDivisionError + # Main test suite class TestCase(unittest.TestCase): @@ -637,6 +641,7 @@ class TestCase(unittest.TestCase): self.assertRaises(TypeError, lambda: 3 in 12) self.assertRaises(TypeError, lambda: 3 not in map) + self.assertRaises(ZeroDivisionError, lambda: 3 in BadIterableClass()) d = {"one": 1, "two": 2, "three": 3, 1j: 2j} for k in d: @@ -719,6 +724,7 @@ class TestCase(unittest.TestCase): self.assertRaises(TypeError, indexOf, 42, 1) self.assertRaises(TypeError, indexOf, indexOf, indexOf) + self.assertRaises(ZeroDivisionError, indexOf, BadIterableClass(), 1) f = open(TESTFN, "w") try: @@ -1006,6 +1012,7 @@ class TestCase(unittest.TestCase): def test_error_iter(self): for typ in (DefaultIterClass, NoIterClass): self.assertRaises(TypeError, iter, typ()) + self.assertRaises(ZeroDivisionError, iter, BadIterableClass()) def test_main(): diff --git a/Lib/test/test_operator.py b/Lib/test/test_operator.py index f46d94a..29f5e42 100644 --- a/Lib/test/test_operator.py +++ b/Lib/test/test_operator.py @@ -35,6 +35,10 @@ class Seq2(object): def __rmul__(self, other): return other * self.lst +class BadIterable: + def __iter__(self): + raise ZeroDivisionError + class OperatorTestCase: def test_lt(self): @@ -142,6 +146,7 @@ class OperatorTestCase: operator = self.module self.assertRaises(TypeError, operator.countOf) self.assertRaises(TypeError, operator.countOf, None, None) + self.assertRaises(ZeroDivisionError, operator.countOf, BadIterable(), 1) self.assertEqual(operator.countOf([1, 2, 1, 3, 1, 4], 3), 1) self.assertEqual(operator.countOf([1, 2, 1, 3, 1, 4], 5), 0) @@ -176,6 +181,7 @@ class OperatorTestCase: operator = self.module self.assertRaises(TypeError, operator.indexOf) self.assertRaises(TypeError, operator.indexOf, None, None) + self.assertRaises(ZeroDivisionError, operator.indexOf, BadIterable(), 1) self.assertEqual(operator.indexOf([4, 3, 2, 1], 3), 1) self.assertRaises(ValueError, operator.indexOf, [4, 3, 2, 1], 0) @@ -258,6 +264,7 @@ class OperatorTestCase: operator = self.module self.assertRaises(TypeError, operator.contains) self.assertRaises(TypeError, operator.contains, None, None) + self.assertRaises(ZeroDivisionError, operator.contains, BadIterable(), 1) self.assertTrue(operator.contains(range(4), 2)) self.assertFalse(operator.contains(range(4), 5)) diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-05-30-14-37-18.bpo-40824.XR3V5s.rst b/Misc/NEWS.d/next/Core and Builtins/2020-05-30-14-37-18.bpo-40824.XR3V5s.rst new file mode 100644 index 0000000..73c593c --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2020-05-30-14-37-18.bpo-40824.XR3V5s.rst @@ -0,0 +1,4 @@ +Unexpected errors in calling the ``__iter__`` method are no longer masked by +``TypeError`` in the :keyword:`in` operator and functions +:func:`~operator.contains`, :func:`~operator.indexOf` and +:func:`~operator.countOf` of the :mod:`operator` module. diff --git a/Objects/abstract.c b/Objects/abstract.c index 4fabfd7..12237d5 100644 --- a/Objects/abstract.c +++ b/Objects/abstract.c @@ -1999,7 +1999,9 @@ _PySequence_IterSearch(PyObject *seq, PyObject *obj, int operation) it = PyObject_GetIter(seq); if (it == NULL) { - type_error("argument of type '%.200s' is not iterable", seq); + if (PyErr_ExceptionMatches(PyExc_TypeError)) { + type_error("argument of type '%.200s' is not iterable", seq); + } return -1; } |