From c571c31dd2237e9a51e77f37737a22bc4af392f2 Mon Sep 17 00:00:00 2001 From: Brandt Bucher Date: Tue, 21 Jun 2022 14:11:26 -0700 Subject: [PATCH 1/3] Add tests for throwing into yield from --- Lib/test/test_yield_from.py | 530 ++++++++++++++++++++++++++++++++++++ 1 file changed, 530 insertions(+) diff --git a/Lib/test/test_yield_from.py b/Lib/test/test_yield_from.py index d105d8c6eb513c..e88c241c6a4bf5 100644 --- a/Lib/test/test_yield_from.py +++ b/Lib/test/test_yield_from.py @@ -7,6 +7,9 @@ see """ +import doctest +from email.generator import Generator +from lib2to3.pytree import Base import unittest import inspect @@ -1049,6 +1052,533 @@ def outer(): g.send((1, 2, 3, 4)) self.assertEqual(v, (1, 2, 3, 4)) +class TestInterestingEdgeCases(unittest.TestCase): + + def assert_stop_iteration(self, iterator): + with self.assertRaises(StopIteration) as caught: + next(iterator) + self.assertIs(caught.exception.value, None) + self.assertIs(caught.exception.__context__, None) + + def assert_generator_raised_stop_iteration(self): + return self.assertRaisesRegex(RuntimeError, r"^generator raised StopIteration$") + + def assert_generator_ignored_generator_exit(self): + return self.assertRaisesRegex(RuntimeError, r"^generator ignored GeneratorExit$") + + def test_close_and_throw_work(self): + + yielded_first = object() + yielded_second = object() + returned = object() + + def inner(): + yield yielded_first + yield yielded_second + return returned + + def outer(): + return (yield from inner()) + + with self.subTest("close"): + g = outer() + self.assertIs(next(g), yielded_first) + g.close() + self.assert_stop_iteration(g) + + with self.subTest("throw GeneratorExit"): + g = outer() + self.assertIs(next(g), yielded_first) + thrown = GeneratorExit() + with self.assertRaises(GeneratorExit) as caught: + g.throw(thrown) + self.assertIs(caught.exception, thrown) + self.assertIs(caught.exception.__context__, None) + self.assert_stop_iteration(g) + + with self.subTest("throw StopIteration"): + g = outer() + self.assertIs(next(g), yielded_first) + thrown = StopIteration() + # PEP 479: + with self.assert_generator_raised_stop_iteration() as caught: + g.throw(thrown) + self.assertIs(caught.exception.__context__, thrown) + self.assertIs(caught.exception.__context__.__context__, None) + self.assert_stop_iteration(g) + + with self.subTest("throw BaseException"): + g = outer() + self.assertIs(next(g), yielded_first) + thrown = BaseException() + with self.assertRaises(BaseException) as caught: + g.throw(thrown) + self.assertIs(caught.exception, thrown) + self.assertIs(caught.exception.__context__, None) + self.assert_stop_iteration(g) + + with self.subTest("throw Exception"): + g = outer() + self.assertIs(next(g), yielded_first) + thrown = Exception() + with self.assertRaises(Exception) as caught: + g.throw(thrown) + self.assertIs(caught.exception, thrown) + self.assertIs(caught.exception.__context__, None) + self.assert_stop_iteration(g) + + def test_close_and_throw_raise_generator_exit(self): + + yielded_first = object() + yielded_second = object() + returned = object() + + def inner(): + try: + yield yielded_first + yield yielded_second + return returned + finally: + raise raised + + def outer(): + return (yield from inner()) + + with self.subTest("close"): + g = outer() + self.assertIs(next(g), yielded_first) + raised = GeneratorExit() + # GeneratorExit is suppressed. This is consistent with PEP 342: + # https://peps.python.org/pep-0342/#new-generator-method-close + g.close() + self.assert_stop_iteration(g) + + with self.subTest("throw GeneratorExit"): + g = outer() + self.assertIs(next(g), yielded_first) + raised = GeneratorExit() + thrown = GeneratorExit() + with self.assertRaises(GeneratorExit) as caught: + g.throw(thrown) + # The raised GeneratorExit is suppressed, but the thrown one + # propagates. This is consistent with PEP 380: + # https://peps.python.org/pep-0380/#proposal + self.assertIs(caught.exception, thrown) + self.assertIs(caught.exception.__context__, None) + self.assert_stop_iteration(g) + + with self.subTest("throw StopIteration"): + g = outer() + self.assertIs(next(g), yielded_first) + raised = GeneratorExit() + thrown = StopIteration() + with self.assertRaises(GeneratorExit) as caught: + g.throw(thrown) + self.assertIs(caught.exception, raised) + self.assertIs(caught.exception.__context__, thrown) + self.assertIs(caught.exception.__context__.__context__, None) + self.assert_stop_iteration(g) + + with self.subTest("throw BaseException"): + g = outer() + self.assertIs(next(g), yielded_first) + raised = GeneratorExit() + thrown = BaseException() + with self.assertRaises(GeneratorExit) as caught: + g.throw(thrown) + self.assertIs(caught.exception, raised) + self.assertIs(caught.exception.__context__, thrown) + self.assertIs(caught.exception.__context__.__context__, None) + self.assert_stop_iteration(g) + + with self.subTest("throw Exception"): + g = outer() + self.assertIs(next(g), yielded_first) + raised = GeneratorExit() + thrown = Exception() + with self.assertRaises(GeneratorExit) as caught: + g.throw(thrown) + self.assertIs(caught.exception, raised) + self.assertIs(caught.exception.__context__, thrown) + self.assertIs(caught.exception.__context__.__context__, None) + self.assert_stop_iteration(g) + + def test_close_and_throw_raise_stop_iteration(self): + + yielded_first = object() + yielded_second = object() + returned = object() + + def inner(): + try: + yield yielded_first + yield yielded_second + return returned + finally: + raise raised + + def outer(): + return (yield from inner()) + + with self.subTest("close"): + g = outer() + self.assertIs(next(g), yielded_first) + raised = StopIteration() + # PEP 479: + with self.assert_generator_raised_stop_iteration() as caught: + g.close() + self.assertIs(caught.exception.__context__, raised) + self.assertIsInstance(caught.exception.__context__.__context__, GeneratorExit) + self.assertIs(caught.exception.__context__.__context__.__context__, None) + self.assert_stop_iteration(g) + + with self.subTest("throw GeneratorExit"): + g = outer() + self.assertIs(next(g), yielded_first) + raised = StopIteration() + thrown = GeneratorExit() + # PEP 479: + with self.assert_generator_raised_stop_iteration() as caught: + g.throw(thrown) + self.assertIs(caught.exception.__context__, raised) + # This isn't the same GeneratorExit as thrown! It's the one created + # by calling inner.close(): + self.assertIsInstance(caught.exception.__context__.__context__, GeneratorExit) + self.assertIs(caught.exception.__context__.__context__.__context__, None) + self.assert_stop_iteration(g) + + with self.subTest("throw StopIteration"): + g = outer() + self.assertIs(next(g), yielded_first) + raised = StopIteration() + thrown = StopIteration() + # PEP 479: + with self.assert_generator_raised_stop_iteration() as caught: + g.throw(thrown) + self.assertIs(caught.exception.__context__, raised) + self.assertIs(caught.exception.__context__.__context__, thrown) + self.assertIs(caught.exception.__context__.__context__.__context__, None) + self.assert_stop_iteration(g) + + with self.subTest("throw BaseException"): + g = outer() + self.assertIs(next(g), yielded_first) + raised = StopIteration() + thrown = BaseException() + # PEP 479: + with self.assert_generator_raised_stop_iteration() as caught: + g.throw(thrown) + self.assertIs(caught.exception.__context__, raised) + self.assertIs(caught.exception.__context__.__context__, thrown) + self.assertIs(caught.exception.__context__.__context__.__context__, None) + self.assert_stop_iteration(g) + + with self.subTest("throw Exception"): + g = outer() + self.assertIs(next(g), yielded_first) + raised = StopIteration() + thrown = Exception() + # PEP 479: + with self.assert_generator_raised_stop_iteration() as caught: + g.throw(thrown) + self.assertIs(caught.exception.__context__, raised) + self.assertIs(caught.exception.__context__.__context__, thrown) + self.assertIs(caught.exception.__context__.__context__.__context__, None) + self.assert_stop_iteration(g) + + def test_close_and_throw_raise_base_exception(self): + + yielded_first = object() + yielded_second = object() + returned = object() + + def inner(): + try: + yield yielded_first + yield yielded_second + return returned + finally: + raise raised + + def outer(): + return (yield from inner()) + + with self.subTest("close"): + g = outer() + self.assertIs(next(g), yielded_first) + raised = BaseException() + with self.assertRaises(BaseException) as caught: + g.close() + self.assertIs(caught.exception, raised) + self.assertIsInstance(caught.exception.__context__, GeneratorExit) + self.assertIs(caught.exception.__context__.__context__, None) + self.assert_stop_iteration(g) + + with self.subTest("throw GeneratorExit"): + g = outer() + self.assertIs(next(g), yielded_first) + raised = BaseException() + thrown = GeneratorExit() + with self.assertRaises(BaseException) as caught: + g.throw(thrown) + self.assertIs(caught.exception, raised) + # This isn't the same GeneratorExit as thrown! It's the one created + # by calling inner.close(): + self.assertIsInstance(caught.exception.__context__, GeneratorExit) + self.assertIs(caught.exception.__context__.__context__, None) + self.assert_stop_iteration(g) + + with self.subTest("throw StopIteration"): + g = outer() + self.assertIs(next(g), yielded_first) + raised = BaseException() + thrown = StopIteration() + with self.assertRaises(BaseException) as caught: + g.throw(thrown) + self.assertIs(caught.exception, raised) + self.assertIs(caught.exception.__context__, thrown) + self.assertIs(caught.exception.__context__.__context__, None) + self.assert_stop_iteration(g) + + with self.subTest("throw BaseException"): + g = outer() + self.assertIs(next(g), yielded_first) + raised = BaseException() + thrown = BaseException() + with self.assertRaises(BaseException) as caught: + g.throw(thrown) + self.assertIs(caught.exception, raised) + self.assertIs(caught.exception.__context__, thrown) + self.assertIs(caught.exception.__context__.__context__, None) + self.assert_stop_iteration(g) + + with self.subTest("throw Exception"): + g = outer() + self.assertIs(next(g), yielded_first) + raised = BaseException() + thrown = Exception() + with self.assertRaises(BaseException) as caught: + g.throw(thrown) + self.assertIs(caught.exception, raised) + self.assertIs(caught.exception.__context__, thrown) + self.assertIs(caught.exception.__context__.__context__, None) + self.assert_stop_iteration(g) + + def test_close_and_throw_raise_exception(self): + + yielded_first = object() + yielded_second = object() + returned = object() + + def inner(): + try: + yield yielded_first + yield yielded_second + return returned + finally: + raise raised + + def outer(): + return (yield from inner()) + + with self.subTest("close"): + g = outer() + self.assertIs(next(g), yielded_first) + raised = Exception() + with self.assertRaises(Exception) as caught: + g.close() + self.assertIs(caught.exception, raised) + self.assertIsInstance(caught.exception.__context__, GeneratorExit) + self.assertIs(caught.exception.__context__.__context__, None) + self.assert_stop_iteration(g) + + with self.subTest("throw GeneratorExit"): + g = outer() + self.assertIs(next(g), yielded_first) + raised = Exception() + thrown = GeneratorExit() + with self.assertRaises(Exception) as caught: + g.throw(thrown) + self.assertIs(caught.exception, raised) + # This isn't the same GeneratorExit as thrown! It's the one created + # by calling inner.close(): + self.assertIsInstance(caught.exception.__context__, GeneratorExit) + self.assertIs(caught.exception.__context__.__context__, None) + self.assert_stop_iteration(g) + + with self.subTest("throw StopIteration"): + g = outer() + self.assertIs(next(g), yielded_first) + raised = Exception() + thrown = StopIteration() + with self.assertRaises(Exception) as caught: + g.throw(thrown) + self.assertIs(caught.exception, raised) + self.assertIs(caught.exception.__context__, thrown) + self.assertIs(caught.exception.__context__.__context__, None) + self.assert_stop_iteration(g) + + with self.subTest("throw BaseException"): + g = outer() + self.assertIs(next(g), yielded_first) + raised = Exception() + thrown = BaseException() + with self.assertRaises(Exception) as caught: + g.throw(thrown) + self.assertIs(caught.exception, raised) + self.assertIs(caught.exception.__context__, thrown) + self.assertIs(caught.exception.__context__.__context__, None) + self.assert_stop_iteration(g) + + with self.subTest("throw Exception"): + g = outer() + self.assertIs(next(g), yielded_first) + raised = Exception() + thrown = Exception() + with self.assertRaises(Exception) as caught: + g.throw(thrown) + self.assertIs(caught.exception, raised) + self.assertIs(caught.exception.__context__, thrown) + self.assertIs(caught.exception.__context__.__context__, None) + self.assert_stop_iteration(g) + + def test_close_and_throw_yield(self): + + yielded_first = object() + yielded_second = object() + returned = object() + + def inner(): + try: + yield yielded_first + finally: + yield yielded_second + return returned + + def outer(): + return (yield from inner()) + + with self.subTest("close"): + g = outer() + self.assertIs(next(g), yielded_first) + # No chaining happens. This is consistent with PEP 342: + # https://peps.python.org/pep-0342/#new-generator-method-close + with self.assert_generator_ignored_generator_exit() as caught: + g.close() + self.assertIs(caught.exception.__context__, None) + self.assert_stop_iteration(g) + + with self.subTest("throw GeneratorExit"): + g = outer() + self.assertIs(next(g), yielded_first) + thrown = GeneratorExit() + # No chaining happens. This is consistent with PEP 342: + # https://peps.python.org/pep-0342/#new-generator-method-close + with self.assert_generator_ignored_generator_exit() as caught: + g.throw(thrown) + self.assertIs(caught.exception.__context__, None) + self.assert_stop_iteration(g) + + with self.subTest("throw StopIteration"): + g = outer() + self.assertIs(next(g), yielded_first) + thrown = StopIteration() + self.assertEqual(g.throw(thrown), yielded_second) + # PEP 479: + with self.assert_generator_raised_stop_iteration() as caught: + next(g) + self.assertIs(caught.exception.__context__, thrown) + self.assertIs(caught.exception.__context__.__context__, None) + self.assert_stop_iteration(g) + + with self.subTest("throw BaseException"): + g = outer() + self.assertIs(next(g), yielded_first) + thrown = BaseException() + self.assertEqual(g.throw(thrown), yielded_second) + with self.assertRaises(BaseException) as caught: + next(g) + self.assertIs(caught.exception, thrown) + self.assertIs(caught.exception.__context__, None) + self.assert_stop_iteration(g) + + with self.subTest("throw Exception"): + g = outer() + self.assertIs(next(g), yielded_first) + thrown = Exception() + self.assertEqual(g.throw(thrown), yielded_second) + with self.assertRaises(Exception) as caught: + next(g) + self.assertIs(caught.exception, thrown) + self.assertIs(caught.exception.__context__, None) + self.assert_stop_iteration(g) + + def test_close_and_throw_return(self): + + yielded_first = object() + yielded_second = object() + returned = object() + + def inner(): + try: + yield yielded_first + yield yielded_second + finally: + return returned + + def outer(): + return (yield from inner()) + + with self.subTest("close"): + g = outer() + self.assertIs(next(g), yielded_first) + # StopIteration is suppressed. This is consistent with PEP 342: + # https://peps.python.org/pep-0342/#new-generator-method-close + g.close() + self.assert_stop_iteration(g) + + with self.subTest("throw GeneratorExit"): + g = outer() + self.assertIs(next(g), yielded_first) + thrown = GeneratorExit() + # StopIteration is suppressed. This is consistent with PEP 342: + # https://peps.python.org/pep-0342/#new-generator-method-close + with self.assertRaises(GeneratorExit) as caught: + g.throw(thrown) + self.assertIs(caught.exception, thrown) + self.assertIs(caught.exception.__context__, None) + self.assert_stop_iteration(g) + + with self.subTest("throw StopIteration"): + g = outer() + self.assertIs(next(g), yielded_first) + thrown = StopIteration() + with self.assertRaises(StopIteration) as caught: + g.throw(thrown) + self.assertIs(caught.exception.value, returned) + self.assertIs(caught.exception.__context__, None) + self.assert_stop_iteration(g) + + with self.subTest("throw BaseException"): + g = outer() + self.assertIs(next(g), yielded_first) + thrown = BaseException() + with self.assertRaises(StopIteration) as caught: + g.throw(thrown) + self.assertIs(caught.exception.value, returned) + self.assertIs(caught.exception.__context__, None) + self.assert_stop_iteration(g) + + with self.subTest("throw Exception"): + g = outer() + self.assertIs(next(g), yielded_first) + thrown = Exception() + with self.assertRaises(StopIteration) as caught: + g.throw(thrown) + self.assertIs(caught.exception.value, returned) + self.assertIs(caught.exception.__context__, None) + self.assert_stop_iteration(g) + if __name__ == '__main__': unittest.main() From 4eccf354226f091ee3a9b6674684e9857d959834 Mon Sep 17 00:00:00 2001 From: Brandt Bucher Date: Tue, 21 Jun 2022 14:15:53 -0700 Subject: [PATCH 2/3] Remove unused imports --- Lib/test/test_yield_from.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/Lib/test/test_yield_from.py b/Lib/test/test_yield_from.py index e88c241c6a4bf5..de47d82af0d5d0 100644 --- a/Lib/test/test_yield_from.py +++ b/Lib/test/test_yield_from.py @@ -7,9 +7,6 @@ see """ -import doctest -from email.generator import Generator -from lib2to3.pytree import Base import unittest import inspect From 586244c763b604e7239c2c55161b4879e5fe995b Mon Sep 17 00:00:00 2001 From: Brandt Bucher Date: Wed, 22 Jun 2022 10:42:46 -0700 Subject: [PATCH 3/3] Use assertIsNone --- Lib/test/test_yield_from.py | 68 ++++++++++++++++++------------------- 1 file changed, 34 insertions(+), 34 deletions(-) diff --git a/Lib/test/test_yield_from.py b/Lib/test/test_yield_from.py index de47d82af0d5d0..1a60357a1bcd62 100644 --- a/Lib/test/test_yield_from.py +++ b/Lib/test/test_yield_from.py @@ -1054,8 +1054,8 @@ class TestInterestingEdgeCases(unittest.TestCase): def assert_stop_iteration(self, iterator): with self.assertRaises(StopIteration) as caught: next(iterator) - self.assertIs(caught.exception.value, None) - self.assertIs(caught.exception.__context__, None) + self.assertIsNone(caught.exception.value) + self.assertIsNone(caught.exception.__context__) def assert_generator_raised_stop_iteration(self): return self.assertRaisesRegex(RuntimeError, r"^generator raised StopIteration$") @@ -1090,7 +1090,7 @@ def outer(): with self.assertRaises(GeneratorExit) as caught: g.throw(thrown) self.assertIs(caught.exception, thrown) - self.assertIs(caught.exception.__context__, None) + self.assertIsNone(caught.exception.__context__) self.assert_stop_iteration(g) with self.subTest("throw StopIteration"): @@ -1101,7 +1101,7 @@ def outer(): with self.assert_generator_raised_stop_iteration() as caught: g.throw(thrown) self.assertIs(caught.exception.__context__, thrown) - self.assertIs(caught.exception.__context__.__context__, None) + self.assertIsNone(caught.exception.__context__.__context__) self.assert_stop_iteration(g) with self.subTest("throw BaseException"): @@ -1111,7 +1111,7 @@ def outer(): with self.assertRaises(BaseException) as caught: g.throw(thrown) self.assertIs(caught.exception, thrown) - self.assertIs(caught.exception.__context__, None) + self.assertIsNone(caught.exception.__context__) self.assert_stop_iteration(g) with self.subTest("throw Exception"): @@ -1121,7 +1121,7 @@ def outer(): with self.assertRaises(Exception) as caught: g.throw(thrown) self.assertIs(caught.exception, thrown) - self.assertIs(caught.exception.__context__, None) + self.assertIsNone(caught.exception.__context__) self.assert_stop_iteration(g) def test_close_and_throw_raise_generator_exit(self): @@ -1161,7 +1161,7 @@ def outer(): # propagates. This is consistent with PEP 380: # https://peps.python.org/pep-0380/#proposal self.assertIs(caught.exception, thrown) - self.assertIs(caught.exception.__context__, None) + self.assertIsNone(caught.exception.__context__) self.assert_stop_iteration(g) with self.subTest("throw StopIteration"): @@ -1173,7 +1173,7 @@ def outer(): g.throw(thrown) self.assertIs(caught.exception, raised) self.assertIs(caught.exception.__context__, thrown) - self.assertIs(caught.exception.__context__.__context__, None) + self.assertIsNone(caught.exception.__context__.__context__) self.assert_stop_iteration(g) with self.subTest("throw BaseException"): @@ -1185,7 +1185,7 @@ def outer(): g.throw(thrown) self.assertIs(caught.exception, raised) self.assertIs(caught.exception.__context__, thrown) - self.assertIs(caught.exception.__context__.__context__, None) + self.assertIsNone(caught.exception.__context__.__context__) self.assert_stop_iteration(g) with self.subTest("throw Exception"): @@ -1197,7 +1197,7 @@ def outer(): g.throw(thrown) self.assertIs(caught.exception, raised) self.assertIs(caught.exception.__context__, thrown) - self.assertIs(caught.exception.__context__.__context__, None) + self.assertIsNone(caught.exception.__context__.__context__) self.assert_stop_iteration(g) def test_close_and_throw_raise_stop_iteration(self): @@ -1226,7 +1226,7 @@ def outer(): g.close() self.assertIs(caught.exception.__context__, raised) self.assertIsInstance(caught.exception.__context__.__context__, GeneratorExit) - self.assertIs(caught.exception.__context__.__context__.__context__, None) + self.assertIsNone(caught.exception.__context__.__context__.__context__) self.assert_stop_iteration(g) with self.subTest("throw GeneratorExit"): @@ -1241,7 +1241,7 @@ def outer(): # This isn't the same GeneratorExit as thrown! It's the one created # by calling inner.close(): self.assertIsInstance(caught.exception.__context__.__context__, GeneratorExit) - self.assertIs(caught.exception.__context__.__context__.__context__, None) + self.assertIsNone(caught.exception.__context__.__context__.__context__) self.assert_stop_iteration(g) with self.subTest("throw StopIteration"): @@ -1254,7 +1254,7 @@ def outer(): g.throw(thrown) self.assertIs(caught.exception.__context__, raised) self.assertIs(caught.exception.__context__.__context__, thrown) - self.assertIs(caught.exception.__context__.__context__.__context__, None) + self.assertIsNone(caught.exception.__context__.__context__.__context__) self.assert_stop_iteration(g) with self.subTest("throw BaseException"): @@ -1267,7 +1267,7 @@ def outer(): g.throw(thrown) self.assertIs(caught.exception.__context__, raised) self.assertIs(caught.exception.__context__.__context__, thrown) - self.assertIs(caught.exception.__context__.__context__.__context__, None) + self.assertIsNone(caught.exception.__context__.__context__.__context__) self.assert_stop_iteration(g) with self.subTest("throw Exception"): @@ -1280,7 +1280,7 @@ def outer(): g.throw(thrown) self.assertIs(caught.exception.__context__, raised) self.assertIs(caught.exception.__context__.__context__, thrown) - self.assertIs(caught.exception.__context__.__context__.__context__, None) + self.assertIsNone(caught.exception.__context__.__context__.__context__) self.assert_stop_iteration(g) def test_close_and_throw_raise_base_exception(self): @@ -1308,7 +1308,7 @@ def outer(): g.close() self.assertIs(caught.exception, raised) self.assertIsInstance(caught.exception.__context__, GeneratorExit) - self.assertIs(caught.exception.__context__.__context__, None) + self.assertIsNone(caught.exception.__context__.__context__) self.assert_stop_iteration(g) with self.subTest("throw GeneratorExit"): @@ -1322,7 +1322,7 @@ def outer(): # This isn't the same GeneratorExit as thrown! It's the one created # by calling inner.close(): self.assertIsInstance(caught.exception.__context__, GeneratorExit) - self.assertIs(caught.exception.__context__.__context__, None) + self.assertIsNone(caught.exception.__context__.__context__) self.assert_stop_iteration(g) with self.subTest("throw StopIteration"): @@ -1334,7 +1334,7 @@ def outer(): g.throw(thrown) self.assertIs(caught.exception, raised) self.assertIs(caught.exception.__context__, thrown) - self.assertIs(caught.exception.__context__.__context__, None) + self.assertIsNone(caught.exception.__context__.__context__) self.assert_stop_iteration(g) with self.subTest("throw BaseException"): @@ -1346,7 +1346,7 @@ def outer(): g.throw(thrown) self.assertIs(caught.exception, raised) self.assertIs(caught.exception.__context__, thrown) - self.assertIs(caught.exception.__context__.__context__, None) + self.assertIsNone(caught.exception.__context__.__context__) self.assert_stop_iteration(g) with self.subTest("throw Exception"): @@ -1358,7 +1358,7 @@ def outer(): g.throw(thrown) self.assertIs(caught.exception, raised) self.assertIs(caught.exception.__context__, thrown) - self.assertIs(caught.exception.__context__.__context__, None) + self.assertIsNone(caught.exception.__context__.__context__) self.assert_stop_iteration(g) def test_close_and_throw_raise_exception(self): @@ -1386,7 +1386,7 @@ def outer(): g.close() self.assertIs(caught.exception, raised) self.assertIsInstance(caught.exception.__context__, GeneratorExit) - self.assertIs(caught.exception.__context__.__context__, None) + self.assertIsNone(caught.exception.__context__.__context__) self.assert_stop_iteration(g) with self.subTest("throw GeneratorExit"): @@ -1400,7 +1400,7 @@ def outer(): # This isn't the same GeneratorExit as thrown! It's the one created # by calling inner.close(): self.assertIsInstance(caught.exception.__context__, GeneratorExit) - self.assertIs(caught.exception.__context__.__context__, None) + self.assertIsNone(caught.exception.__context__.__context__) self.assert_stop_iteration(g) with self.subTest("throw StopIteration"): @@ -1412,7 +1412,7 @@ def outer(): g.throw(thrown) self.assertIs(caught.exception, raised) self.assertIs(caught.exception.__context__, thrown) - self.assertIs(caught.exception.__context__.__context__, None) + self.assertIsNone(caught.exception.__context__.__context__) self.assert_stop_iteration(g) with self.subTest("throw BaseException"): @@ -1424,7 +1424,7 @@ def outer(): g.throw(thrown) self.assertIs(caught.exception, raised) self.assertIs(caught.exception.__context__, thrown) - self.assertIs(caught.exception.__context__.__context__, None) + self.assertIsNone(caught.exception.__context__.__context__) self.assert_stop_iteration(g) with self.subTest("throw Exception"): @@ -1436,7 +1436,7 @@ def outer(): g.throw(thrown) self.assertIs(caught.exception, raised) self.assertIs(caught.exception.__context__, thrown) - self.assertIs(caught.exception.__context__.__context__, None) + self.assertIsNone(caught.exception.__context__.__context__) self.assert_stop_iteration(g) def test_close_and_throw_yield(self): @@ -1462,7 +1462,7 @@ def outer(): # https://peps.python.org/pep-0342/#new-generator-method-close with self.assert_generator_ignored_generator_exit() as caught: g.close() - self.assertIs(caught.exception.__context__, None) + self.assertIsNone(caught.exception.__context__) self.assert_stop_iteration(g) with self.subTest("throw GeneratorExit"): @@ -1473,7 +1473,7 @@ def outer(): # https://peps.python.org/pep-0342/#new-generator-method-close with self.assert_generator_ignored_generator_exit() as caught: g.throw(thrown) - self.assertIs(caught.exception.__context__, None) + self.assertIsNone(caught.exception.__context__) self.assert_stop_iteration(g) with self.subTest("throw StopIteration"): @@ -1485,7 +1485,7 @@ def outer(): with self.assert_generator_raised_stop_iteration() as caught: next(g) self.assertIs(caught.exception.__context__, thrown) - self.assertIs(caught.exception.__context__.__context__, None) + self.assertIsNone(caught.exception.__context__.__context__) self.assert_stop_iteration(g) with self.subTest("throw BaseException"): @@ -1496,7 +1496,7 @@ def outer(): with self.assertRaises(BaseException) as caught: next(g) self.assertIs(caught.exception, thrown) - self.assertIs(caught.exception.__context__, None) + self.assertIsNone(caught.exception.__context__) self.assert_stop_iteration(g) with self.subTest("throw Exception"): @@ -1507,7 +1507,7 @@ def outer(): with self.assertRaises(Exception) as caught: next(g) self.assertIs(caught.exception, thrown) - self.assertIs(caught.exception.__context__, None) + self.assertIsNone(caught.exception.__context__) self.assert_stop_iteration(g) def test_close_and_throw_return(self): @@ -1543,7 +1543,7 @@ def outer(): with self.assertRaises(GeneratorExit) as caught: g.throw(thrown) self.assertIs(caught.exception, thrown) - self.assertIs(caught.exception.__context__, None) + self.assertIsNone(caught.exception.__context__) self.assert_stop_iteration(g) with self.subTest("throw StopIteration"): @@ -1553,7 +1553,7 @@ def outer(): with self.assertRaises(StopIteration) as caught: g.throw(thrown) self.assertIs(caught.exception.value, returned) - self.assertIs(caught.exception.__context__, None) + self.assertIsNone(caught.exception.__context__) self.assert_stop_iteration(g) with self.subTest("throw BaseException"): @@ -1563,7 +1563,7 @@ def outer(): with self.assertRaises(StopIteration) as caught: g.throw(thrown) self.assertIs(caught.exception.value, returned) - self.assertIs(caught.exception.__context__, None) + self.assertIsNone(caught.exception.__context__) self.assert_stop_iteration(g) with self.subTest("throw Exception"): @@ -1573,7 +1573,7 @@ def outer(): with self.assertRaises(StopIteration) as caught: g.throw(thrown) self.assertIs(caught.exception.value, returned) - self.assertIs(caught.exception.__context__, None) + self.assertIsNone(caught.exception.__context__) self.assert_stop_iteration(g)