mirror of
				https://github.com/python/cpython.git
				synced 2025-10-26 11:14:33 +00:00 
			
		
		
		
	 0025350294
			
		
	
	
		0025350294
		
			
		
	
	
	
	
		
			
			Modify test_coroutines, test_cprofile, test_generators, test_raise, test_ssl and test_yield_from to use support.catch_unraisable_exception() rather than support.captured_stderr(). test_thread: remove test_save_exception_state_on_error() which is now updated. test_unraisable_exception() checks that sys.unraisablehook() is called to handle _thread.start_new_thread() exception. test_cprofile now rely on unittest for test discovery: replace support.run_unittest() with unittest.main().
		
			
				
	
	
		
			487 lines
		
	
	
	
		
			13 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			487 lines
		
	
	
	
		
			13 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
| # Copyright 2007 Google, Inc. All Rights Reserved.
 | |
| # Licensed to PSF under a Contributor Agreement.
 | |
| 
 | |
| """Tests for the raise statement."""
 | |
| 
 | |
| from test import support
 | |
| import sys
 | |
| import types
 | |
| import unittest
 | |
| 
 | |
| 
 | |
| def get_tb():
 | |
|     try:
 | |
|         raise OSError()
 | |
|     except:
 | |
|         return sys.exc_info()[2]
 | |
| 
 | |
| 
 | |
| class Context:
 | |
|     def __enter__(self):
 | |
|         return self
 | |
|     def __exit__(self, exc_type, exc_value, exc_tb):
 | |
|         return True
 | |
| 
 | |
| 
 | |
| class TestRaise(unittest.TestCase):
 | |
|     def test_invalid_reraise(self):
 | |
|         try:
 | |
|             raise
 | |
|         except RuntimeError as e:
 | |
|             self.assertIn("No active exception", str(e))
 | |
|         else:
 | |
|             self.fail("No exception raised")
 | |
| 
 | |
|     def test_reraise(self):
 | |
|         try:
 | |
|             try:
 | |
|                 raise IndexError()
 | |
|             except IndexError as e:
 | |
|                 exc1 = e
 | |
|                 raise
 | |
|         except IndexError as exc2:
 | |
|             self.assertIs(exc1, exc2)
 | |
|         else:
 | |
|             self.fail("No exception raised")
 | |
| 
 | |
|     def test_except_reraise(self):
 | |
|         def reraise():
 | |
|             try:
 | |
|                 raise TypeError("foo")
 | |
|             except:
 | |
|                 try:
 | |
|                     raise KeyError("caught")
 | |
|                 except KeyError:
 | |
|                     pass
 | |
|                 raise
 | |
|         self.assertRaises(TypeError, reraise)
 | |
| 
 | |
|     def test_finally_reraise(self):
 | |
|         def reraise():
 | |
|             try:
 | |
|                 raise TypeError("foo")
 | |
|             except:
 | |
|                 try:
 | |
|                     raise KeyError("caught")
 | |
|                 finally:
 | |
|                     raise
 | |
|         self.assertRaises(KeyError, reraise)
 | |
| 
 | |
|     def test_nested_reraise(self):
 | |
|         def nested_reraise():
 | |
|             raise
 | |
|         def reraise():
 | |
|             try:
 | |
|                 raise TypeError("foo")
 | |
|             except:
 | |
|                 nested_reraise()
 | |
|         self.assertRaises(TypeError, reraise)
 | |
| 
 | |
|     def test_raise_from_None(self):
 | |
|         try:
 | |
|             try:
 | |
|                 raise TypeError("foo")
 | |
|             except:
 | |
|                 raise ValueError() from None
 | |
|         except ValueError as e:
 | |
|             self.assertIsInstance(e.__context__, TypeError)
 | |
|             self.assertIsNone(e.__cause__)
 | |
| 
 | |
|     def test_with_reraise1(self):
 | |
|         def reraise():
 | |
|             try:
 | |
|                 raise TypeError("foo")
 | |
|             except:
 | |
|                 with Context():
 | |
|                     pass
 | |
|                 raise
 | |
|         self.assertRaises(TypeError, reraise)
 | |
| 
 | |
|     def test_with_reraise2(self):
 | |
|         def reraise():
 | |
|             try:
 | |
|                 raise TypeError("foo")
 | |
|             except:
 | |
|                 with Context():
 | |
|                     raise KeyError("caught")
 | |
|                 raise
 | |
|         self.assertRaises(TypeError, reraise)
 | |
| 
 | |
|     def test_yield_reraise(self):
 | |
|         def reraise():
 | |
|             try:
 | |
|                 raise TypeError("foo")
 | |
|             except:
 | |
|                 yield 1
 | |
|                 raise
 | |
|         g = reraise()
 | |
|         next(g)
 | |
|         self.assertRaises(TypeError, lambda: next(g))
 | |
|         self.assertRaises(StopIteration, lambda: next(g))
 | |
| 
 | |
|     def test_erroneous_exception(self):
 | |
|         class MyException(Exception):
 | |
|             def __init__(self):
 | |
|                 raise RuntimeError()
 | |
| 
 | |
|         try:
 | |
|             raise MyException
 | |
|         except RuntimeError:
 | |
|             pass
 | |
|         else:
 | |
|             self.fail("No exception raised")
 | |
| 
 | |
|     def test_new_returns_invalid_instance(self):
 | |
|         # See issue #11627.
 | |
|         class MyException(Exception):
 | |
|             def __new__(cls, *args):
 | |
|                 return object()
 | |
| 
 | |
|         with self.assertRaises(TypeError):
 | |
|             raise MyException
 | |
| 
 | |
|     def test_assert_with_tuple_arg(self):
 | |
|         try:
 | |
|             assert False, (3,)
 | |
|         except AssertionError as e:
 | |
|             self.assertEqual(str(e), "(3,)")
 | |
| 
 | |
| 
 | |
| 
 | |
| class TestCause(unittest.TestCase):
 | |
| 
 | |
|     def testCauseSyntax(self):
 | |
|         try:
 | |
|             try:
 | |
|                 try:
 | |
|                     raise TypeError
 | |
|                 except Exception:
 | |
|                     raise ValueError from None
 | |
|             except ValueError as exc:
 | |
|                 self.assertIsNone(exc.__cause__)
 | |
|                 self.assertTrue(exc.__suppress_context__)
 | |
|                 exc.__suppress_context__ = False
 | |
|                 raise exc
 | |
|         except ValueError as exc:
 | |
|             e = exc
 | |
| 
 | |
|         self.assertIsNone(e.__cause__)
 | |
|         self.assertFalse(e.__suppress_context__)
 | |
|         self.assertIsInstance(e.__context__, TypeError)
 | |
| 
 | |
|     def test_invalid_cause(self):
 | |
|         try:
 | |
|             raise IndexError from 5
 | |
|         except TypeError as e:
 | |
|             self.assertIn("exception cause", str(e))
 | |
|         else:
 | |
|             self.fail("No exception raised")
 | |
| 
 | |
|     def test_class_cause(self):
 | |
|         try:
 | |
|             raise IndexError from KeyError
 | |
|         except IndexError as e:
 | |
|             self.assertIsInstance(e.__cause__, KeyError)
 | |
|         else:
 | |
|             self.fail("No exception raised")
 | |
| 
 | |
|     def test_instance_cause(self):
 | |
|         cause = KeyError()
 | |
|         try:
 | |
|             raise IndexError from cause
 | |
|         except IndexError as e:
 | |
|             self.assertIs(e.__cause__, cause)
 | |
|         else:
 | |
|             self.fail("No exception raised")
 | |
| 
 | |
|     def test_erroneous_cause(self):
 | |
|         class MyException(Exception):
 | |
|             def __init__(self):
 | |
|                 raise RuntimeError()
 | |
| 
 | |
|         try:
 | |
|             raise IndexError from MyException
 | |
|         except RuntimeError:
 | |
|             pass
 | |
|         else:
 | |
|             self.fail("No exception raised")
 | |
| 
 | |
| 
 | |
| class TestTraceback(unittest.TestCase):
 | |
| 
 | |
|     def test_sets_traceback(self):
 | |
|         try:
 | |
|             raise IndexError()
 | |
|         except IndexError as e:
 | |
|             self.assertIsInstance(e.__traceback__, types.TracebackType)
 | |
|         else:
 | |
|             self.fail("No exception raised")
 | |
| 
 | |
|     def test_accepts_traceback(self):
 | |
|         tb = get_tb()
 | |
|         try:
 | |
|             raise IndexError().with_traceback(tb)
 | |
|         except IndexError as e:
 | |
|             self.assertNotEqual(e.__traceback__, tb)
 | |
|             self.assertEqual(e.__traceback__.tb_next, tb)
 | |
|         else:
 | |
|             self.fail("No exception raised")
 | |
| 
 | |
| 
 | |
| class TestTracebackType(unittest.TestCase):
 | |
| 
 | |
|     def raiser(self):
 | |
|         raise ValueError
 | |
| 
 | |
|     def test_attrs(self):
 | |
|         try:
 | |
|             self.raiser()
 | |
|         except Exception as exc:
 | |
|             tb = exc.__traceback__
 | |
| 
 | |
|         self.assertIsInstance(tb.tb_next, types.TracebackType)
 | |
|         self.assertIs(tb.tb_frame, sys._getframe())
 | |
|         self.assertIsInstance(tb.tb_lasti, int)
 | |
|         self.assertIsInstance(tb.tb_lineno, int)
 | |
| 
 | |
|         self.assertIs(tb.tb_next.tb_next, None)
 | |
| 
 | |
|         # Invalid assignments
 | |
|         with self.assertRaises(TypeError):
 | |
|             del tb.tb_next
 | |
| 
 | |
|         with self.assertRaises(TypeError):
 | |
|             tb.tb_next = "asdf"
 | |
| 
 | |
|         # Loops
 | |
|         with self.assertRaises(ValueError):
 | |
|             tb.tb_next = tb
 | |
| 
 | |
|         with self.assertRaises(ValueError):
 | |
|             tb.tb_next.tb_next = tb
 | |
| 
 | |
|         # Valid assignments
 | |
|         tb.tb_next = None
 | |
|         self.assertIs(tb.tb_next, None)
 | |
| 
 | |
|         new_tb = get_tb()
 | |
|         tb.tb_next = new_tb
 | |
|         self.assertIs(tb.tb_next, new_tb)
 | |
| 
 | |
|     def test_constructor(self):
 | |
|         other_tb = get_tb()
 | |
|         frame = sys._getframe()
 | |
| 
 | |
|         tb = types.TracebackType(other_tb, frame, 1, 2)
 | |
|         self.assertEqual(tb.tb_next, other_tb)
 | |
|         self.assertEqual(tb.tb_frame, frame)
 | |
|         self.assertEqual(tb.tb_lasti, 1)
 | |
|         self.assertEqual(tb.tb_lineno, 2)
 | |
| 
 | |
|         tb = types.TracebackType(None, frame, 1, 2)
 | |
|         self.assertEqual(tb.tb_next, None)
 | |
| 
 | |
|         with self.assertRaises(TypeError):
 | |
|             types.TracebackType("no", frame, 1, 2)
 | |
| 
 | |
|         with self.assertRaises(TypeError):
 | |
|             types.TracebackType(other_tb, "no", 1, 2)
 | |
| 
 | |
|         with self.assertRaises(TypeError):
 | |
|             types.TracebackType(other_tb, frame, "no", 2)
 | |
| 
 | |
|         with self.assertRaises(TypeError):
 | |
|             types.TracebackType(other_tb, frame, 1, "nuh-uh")
 | |
| 
 | |
| 
 | |
| class TestContext(unittest.TestCase):
 | |
|     def test_instance_context_instance_raise(self):
 | |
|         context = IndexError()
 | |
|         try:
 | |
|             try:
 | |
|                 raise context
 | |
|             except:
 | |
|                 raise OSError()
 | |
|         except OSError as e:
 | |
|             self.assertEqual(e.__context__, context)
 | |
|         else:
 | |
|             self.fail("No exception raised")
 | |
| 
 | |
|     def test_class_context_instance_raise(self):
 | |
|         context = IndexError
 | |
|         try:
 | |
|             try:
 | |
|                 raise context
 | |
|             except:
 | |
|                 raise OSError()
 | |
|         except OSError as e:
 | |
|             self.assertNotEqual(e.__context__, context)
 | |
|             self.assertIsInstance(e.__context__, context)
 | |
|         else:
 | |
|             self.fail("No exception raised")
 | |
| 
 | |
|     def test_class_context_class_raise(self):
 | |
|         context = IndexError
 | |
|         try:
 | |
|             try:
 | |
|                 raise context
 | |
|             except:
 | |
|                 raise OSError
 | |
|         except OSError as e:
 | |
|             self.assertNotEqual(e.__context__, context)
 | |
|             self.assertIsInstance(e.__context__, context)
 | |
|         else:
 | |
|             self.fail("No exception raised")
 | |
| 
 | |
|     def test_c_exception_context(self):
 | |
|         try:
 | |
|             try:
 | |
|                 1/0
 | |
|             except:
 | |
|                 raise OSError
 | |
|         except OSError as e:
 | |
|             self.assertIsInstance(e.__context__, ZeroDivisionError)
 | |
|         else:
 | |
|             self.fail("No exception raised")
 | |
| 
 | |
|     def test_c_exception_raise(self):
 | |
|         try:
 | |
|             try:
 | |
|                 1/0
 | |
|             except:
 | |
|                 xyzzy
 | |
|         except NameError as e:
 | |
|             self.assertIsInstance(e.__context__, ZeroDivisionError)
 | |
|         else:
 | |
|             self.fail("No exception raised")
 | |
| 
 | |
|     def test_noraise_finally(self):
 | |
|         try:
 | |
|             try:
 | |
|                 pass
 | |
|             finally:
 | |
|                 raise OSError
 | |
|         except OSError as e:
 | |
|             self.assertIsNone(e.__context__)
 | |
|         else:
 | |
|             self.fail("No exception raised")
 | |
| 
 | |
|     def test_raise_finally(self):
 | |
|         try:
 | |
|             try:
 | |
|                 1/0
 | |
|             finally:
 | |
|                 raise OSError
 | |
|         except OSError as e:
 | |
|             self.assertIsInstance(e.__context__, ZeroDivisionError)
 | |
|         else:
 | |
|             self.fail("No exception raised")
 | |
| 
 | |
|     def test_context_manager(self):
 | |
|         class ContextManager:
 | |
|             def __enter__(self):
 | |
|                 pass
 | |
|             def __exit__(self, t, v, tb):
 | |
|                 xyzzy
 | |
|         try:
 | |
|             with ContextManager():
 | |
|                 1/0
 | |
|         except NameError as e:
 | |
|             self.assertIsInstance(e.__context__, ZeroDivisionError)
 | |
|         else:
 | |
|             self.fail("No exception raised")
 | |
| 
 | |
|     def test_cycle_broken(self):
 | |
|         # Self-cycles (when re-raising a caught exception) are broken
 | |
|         try:
 | |
|             try:
 | |
|                 1/0
 | |
|             except ZeroDivisionError as e:
 | |
|                 raise e
 | |
|         except ZeroDivisionError as e:
 | |
|             self.assertIsNone(e.__context__)
 | |
| 
 | |
|     def test_reraise_cycle_broken(self):
 | |
|         # Non-trivial context cycles (through re-raising a previous exception)
 | |
|         # are broken too.
 | |
|         try:
 | |
|             try:
 | |
|                 xyzzy
 | |
|             except NameError as a:
 | |
|                 try:
 | |
|                     1/0
 | |
|                 except ZeroDivisionError:
 | |
|                     raise a
 | |
|         except NameError as e:
 | |
|             self.assertIsNone(e.__context__.__context__)
 | |
| 
 | |
|     def test_3118(self):
 | |
|         # deleting the generator caused the __context__ to be cleared
 | |
|         def gen():
 | |
|             try:
 | |
|                 yield 1
 | |
|             finally:
 | |
|                 pass
 | |
| 
 | |
|         def f():
 | |
|             g = gen()
 | |
|             next(g)
 | |
|             try:
 | |
|                 try:
 | |
|                     raise ValueError
 | |
|                 except:
 | |
|                     del g
 | |
|                     raise KeyError
 | |
|             except Exception as e:
 | |
|                 self.assertIsInstance(e.__context__, ValueError)
 | |
| 
 | |
|         f()
 | |
| 
 | |
|     def test_3611(self):
 | |
|         # A re-raised exception in a __del__ caused the __context__
 | |
|         # to be cleared
 | |
|         class C:
 | |
|             def __del__(self):
 | |
|                 try:
 | |
|                     1/0
 | |
|                 except:
 | |
|                     raise
 | |
| 
 | |
|         def f():
 | |
|             x = C()
 | |
|             try:
 | |
|                 try:
 | |
|                     x.x
 | |
|                 except AttributeError:
 | |
|                     del x
 | |
|                     raise TypeError
 | |
|             except Exception as e:
 | |
|                 self.assertNotEqual(e.__context__, None)
 | |
|                 self.assertIsInstance(e.__context__, AttributeError)
 | |
| 
 | |
|         with support.catch_unraisable_exception() as cm:
 | |
|             f()
 | |
| 
 | |
|             self.assertEqual(ZeroDivisionError, cm.unraisable.exc_type)
 | |
| 
 | |
| 
 | |
| class TestRemovedFunctionality(unittest.TestCase):
 | |
|     def test_tuples(self):
 | |
|         try:
 | |
|             raise (IndexError, KeyError) # This should be a tuple!
 | |
|         except TypeError:
 | |
|             pass
 | |
|         else:
 | |
|             self.fail("No exception raised")
 | |
| 
 | |
|     def test_strings(self):
 | |
|         try:
 | |
|             raise "foo"
 | |
|         except TypeError:
 | |
|             pass
 | |
|         else:
 | |
|             self.fail("No exception raised")
 | |
| 
 | |
| 
 | |
| if __name__ == "__main__":
 | |
|     unittest.main()
 |