cpython/Lib/test/test_raise.py

329 lines
8.6 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.failUnless("No active exception" in 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.failUnless(exc1 is 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_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")
class TestCause(unittest.TestCase):
def test_invalid_cause(self):
try:
raise IndexError from 5
except TypeError as e:
self.failUnless("exception cause" in str(e))
else:
self.fail("No exception raised")
def test_class_cause(self):
try:
raise IndexError from KeyError
except IndexError as e:
self.failUnless(isinstance(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.failUnless(e.__cause__ is 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.failUnless(isinstance(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 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.failUnless(isinstance(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.failUnless(isinstance(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.failUnless(isinstance(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.failUnless(isinstance(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.failUnless(e.__context__ is None)
else:
self.fail("No exception raised")
def test_raise_finally(self):
try:
try:
1/0
finally:
raise OSError
except OSError as e:
self.failUnless(isinstance(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.failUnless(isinstance(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.failUnless(e.__context__ is None, 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.failUnless(e.__context__.__context__ is None)
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")
def test_main():
support.run_unittest(__name__)
if __name__ == "__main__":
unittest.main()