diff options
Diffstat (limited to 'Lib/test')
-rw-r--r-- | Lib/test/test_generators.py | 109 |
1 files changed, 109 insertions, 0 deletions
diff --git a/Lib/test/test_generators.py b/Lib/test/test_generators.py index 91afe47799..7825a77339 100644 --- a/Lib/test/test_generators.py +++ b/Lib/test/test_generators.py @@ -50,6 +50,115 @@ class FinalizationTest(unittest.TestCase): self.assertEqual(gc.garbage, old_garbage) +class ExceptionTest(unittest.TestCase): + # Tests for the issue #23353: check that the currently handled exception + # is correctly saved/restored in PyEval_EvalFrameEx(). + + def test_except_throw(self): + def store_raise_exc_generator(): + try: + self.assertEqual(sys.exc_info()[0], None) + yield + except Exception as exc: + # exception raised by gen.throw(exc) + self.assertEqual(sys.exc_info()[0], ValueError) + self.assertIsNone(exc.__context__) + yield + + # ensure that the exception is not lost + self.assertEqual(sys.exc_info()[0], ValueError) + yield + + # we should be able to raise back the ValueError + raise + + make = store_raise_exc_generator() + next(make) + + try: + raise ValueError() + except Exception as exc: + try: + make.throw(exc) + except Exception: + pass + + next(make) + with self.assertRaises(ValueError) as cm: + next(make) + self.assertIsNone(cm.exception.__context__) + + self.assertEqual(sys.exc_info(), (None, None, None)) + + def test_except_next(self): + def gen(): + self.assertEqual(sys.exc_info()[0], ValueError) + yield "done" + + g = gen() + try: + raise ValueError + except Exception: + self.assertEqual(next(g), "done") + self.assertEqual(sys.exc_info(), (None, None, None)) + + def test_except_gen_except(self): + def gen(): + try: + self.assertEqual(sys.exc_info()[0], None) + yield + # we are called from "except ValueError:", TypeError must + # inherit ValueError in its context + raise TypeError() + except TypeError as exc: + self.assertEqual(sys.exc_info()[0], TypeError) + self.assertEqual(type(exc.__context__), ValueError) + # here we are still called from the "except ValueError:" + self.assertEqual(sys.exc_info()[0], ValueError) + yield + self.assertIsNone(sys.exc_info()[0]) + yield "done" + + g = gen() + next(g) + try: + raise ValueError + except Exception: + next(g) + + self.assertEqual(next(g), "done") + self.assertEqual(sys.exc_info(), (None, None, None)) + + def test_except_throw_exception_context(self): + def gen(): + try: + try: + self.assertEqual(sys.exc_info()[0], None) + yield + except ValueError: + # we are called from "except ValueError:" + self.assertEqual(sys.exc_info()[0], ValueError) + raise TypeError() + except Exception as exc: + self.assertEqual(sys.exc_info()[0], TypeError) + self.assertEqual(type(exc.__context__), ValueError) + # we are still called from "except ValueError:" + self.assertEqual(sys.exc_info()[0], ValueError) + yield + self.assertIsNone(sys.exc_info()[0]) + yield "done" + + g = gen() + next(g) + try: + raise ValueError + except Exception as exc: + g.throw(exc) + + self.assertEqual(next(g), "done") + self.assertEqual(sys.exc_info(), (None, None, None)) + + tutorial_tests = """ Let's try a simple generator: |