changeset: 95051:b29342f53174 parent: 95049:008fc72fd94d parent: 95050:ac43268da908 user: Antoine Pitrou date: Wed Mar 18 22:23:40 2015 +0100 description: Issue #23353: improve exceptions tests for generators diff -r 008fc72fd94d -r b29342f53174 Lib/test/test_exceptions.py --- a/Lib/test/test_exceptions.py Wed Mar 18 21:53:15 2015 +0200 +++ b/Lib/test/test_exceptions.py Wed Mar 18 22:23:40 2015 +0100 @@ -661,6 +661,52 @@ pass self.assertEqual(sys.exc_info(), (None, None, None)) + def test_generator_leaking3(self): + # See issue #23353. When gen.throw() is called, the caller's + # exception state should be save and restored. + def g(): + try: + yield + except ZeroDivisionError: + yield sys.exc_info()[1] + it = g() + next(it) + try: + 1/0 + except ZeroDivisionError as e: + self.assertIs(sys.exc_info()[1], e) + gen_exc = it.throw(e) + self.assertIs(sys.exc_info()[1], e) + self.assertIs(gen_exc, e) + self.assertEqual(sys.exc_info(), (None, None, None)) + + def test_generator_leaking4(self): + # See issue #23353. When an exception is raised by a generator, + # the caller's exception state should still be restored. + def g(): + try: + 1/0 + except ZeroDivisionError: + yield sys.exc_info()[0] + raise + it = g() + try: + raise TypeError + except TypeError: + # The caller's exception state (TypeError) is temporarily + # saved in the generator. + tp = next(it) + self.assertIs(tp, ZeroDivisionError) + try: + next(it) + # We can't check it immediately, but while next() returns + # with an exception, it shouldn't have restored the old + # exception state (TypeError). + except ZeroDivisionError as e: + self.assertIs(sys.exc_info()[1], e) + # We used to find TypeError here. + self.assertEqual(sys.exc_info(), (None, None, None)) + def test_generator_doesnt_retain_old_exc(self): def g(): self.assertIsInstance(sys.exc_info()[1], RuntimeError)