# Python test set -- part 5, built-in exceptions

import os
import sys
import unittest
import pickle, cPickle

from test.test_support import (TESTFN, unlink, run_unittest, captured_stderr,
                               check_warnings, cpython_only)
from test.test_pep352 import ignore_deprecation_warnings

class BrokenStrException(Exception):
    def __str__(self):
        raise Exception("str() is broken")
    __repr__ = __str__  # Python 2's PyErr_WriteUnraisable() uses repr()

# XXX This is not really enough, each *operation* should be tested!

class ExceptionTests(unittest.TestCase):

    def testReload(self):
        # Reloading the built-in exceptions module failed prior to Py2.2, while it
        # should act the same as reloading built-in sys.
        try:
            from imp import reload
            import exceptions
            reload(exceptions)
        except ImportError, e:
            self.fail("reloading exceptions: %s" % e)

    def raise_catch(self, exc, excname):
        try:
            raise exc, "spam"
        except exc, err:
            buf1 = str(err)
        try:
            raise exc("spam")
        except exc, err:
            buf2 = str(err)
        self.assertEqual(buf1, buf2)
        self.assertEqual(exc.__name__, excname)

    def testRaising(self):
        self.raise_catch(AttributeError, "AttributeError")
        self.assertRaises(AttributeError, getattr, sys, "undefined_attribute")

        self.raise_catch(EOFError, "EOFError")
        fp = open(TESTFN, 'w')
        fp.close()
        fp = open(TESTFN, 'r')
        savestdin = sys.stdin
        try:
            try:
                sys.stdin = fp
                x = raw_input()
            except EOFError:
                pass
        finally:
            sys.stdin = savestdin
            fp.close()
            unlink(TESTFN)

        self.raise_catch(IOError, "IOError")
        self.assertRaises(IOError, open, 'this file does not exist', 'r')

        self.raise_catch(ImportError, "ImportError")
        self.assertRaises(ImportError, __import__, "undefined_module")

        self.raise_catch(IndexError, "IndexError")
        x = []
        self.assertRaises(IndexError, x.__getitem__, 10)

        self.raise_catch(KeyError, "KeyError")
        x = {}
        self.assertRaises(KeyError, x.__getitem__, 'key')

        self.raise_catch(KeyboardInterrupt, "KeyboardInterrupt")

        self.raise_catch(MemoryError, "MemoryError")

        self.raise_catch(NameError, "NameError")
        try: x = undefined_variable
        except NameError: pass

        self.raise_catch(OverflowError, "OverflowError")
        x = 1
        for dummy in range(128):
            x += x  # this simply shouldn't blow up

        self.raise_catch(RuntimeError, "RuntimeError")

        self.raise_catch(SyntaxError, "SyntaxError")
        try: exec '/\n'
        except SyntaxError: pass

        self.raise_catch(IndentationError, "IndentationError")

        self.raise_catch(TabError, "TabError")
        # can only be tested under -tt, and is the only test for -tt
        #try: compile("try:\n\t1.0/0.0\n    \t1.0/0.0\nfinally:\n pass\n", '<string>', 'exec')
        #except TabError: pass
        #else: self.fail("TabError not raised")

        self.raise_catch(SystemError, "SystemError")

        self.raise_catch(SystemExit, "SystemExit")
        self.assertRaises(SystemExit, sys.exit, 0)

        self.raise_catch(TypeError, "TypeError")
        try: [] + ()
        except TypeError: pass

        self.raise_catch(ValueError, "ValueError")
        self.assertRaises(ValueError, chr, 10000)

        self.raise_catch(ZeroDivisionError, "ZeroDivisionError")
        try: x = 1 // 0
        except ZeroDivisionError: pass

        self.raise_catch(Exception, "Exception")
        try: x = 1 // 0
        except Exception, e: pass

    def testSyntaxErrorMessage(self):
        # make sure the right exception message is raised for each of
        # these code fragments

        def ckmsg(src, msg):
            try:
                compile(src, '<fragment>', 'exec')
            except SyntaxError, e:
                if e.msg != msg:
                    self.fail("expected %s, got %s" % (msg, e.msg))
            else:
                self.fail("failed to get expected SyntaxError")

        s = '''while 1:
            try:
                pass
            finally:
                continue'''

        if not sys.platform.startswith('java'):
            ckmsg(s, "'continue' not supported inside 'finally' clause")

        s = '''if 1:
        try:
            continue
        except:
            pass'''

        ckmsg(s, "'continue' not properly in loop")
        ckmsg("continue\n", "'continue' not properly in loop")

    @cpython_only
    def testSettingException(self):
        # test that setting an exception at the C level works even if the
        # exception object can't be constructed.

        class BadException:
            def __init__(self_):
                raise RuntimeError, "can't instantiate BadException"

        def test_capi1():
            import _testcapi
            try:
                _testcapi.raise_exception(BadException, 1)
            except TypeError, err:
                exc, err, tb = sys.exc_info()
                co = tb.tb_frame.f_code
                self.assertEqual(co.co_name, "test_capi1")
                self.assertTrue(co.co_filename.endswith('test_exceptions'+os.extsep+'py'))
            else:
                self.fail("Expected exception")

        def test_capi2():
            import _testcapi
            try:
                _testcapi.raise_exception(BadException, 0)
            except RuntimeError, err:
                exc, err, tb = sys.exc_info()
                co = tb.tb_frame.f_code
                self.assertEqual(co.co_name, "__init__")
                self.assertTrue(co.co_filename.endswith('test_exceptions'+os.extsep+'py'))
                co2 = tb.tb_frame.f_back.f_code
                self.assertEqual(co2.co_name, "test_capi2")
            else:
                self.fail("Expected exception")

        if not sys.platform.startswith('java'):
            test_capi1()
            test_capi2()

    def test_WindowsError(self):
        try:
            WindowsError
        except NameError:
            pass
        else:
            self.assertEqual(str(WindowsError(1001)),
                                 "1001")
            self.assertEqual(str(WindowsError(1001, "message")),
                                 "[Error 1001] message")
            self.assertEqual(WindowsError(1001, "message").errno, 22)
            self.assertEqual(WindowsError(1001, "message").winerror, 1001)

    @ignore_deprecation_warnings
    def testAttributes(self):
        # test that exception attributes are happy

        exceptionList = [
            (BaseException, (), {'message' : '', 'args' : ()}),
            (BaseException, (1, ), {'message' : 1, 'args' : (1,)}),
            (BaseException, ('foo',),
                {'message' : 'foo', 'args' : ('foo',)}),
            (BaseException, ('foo', 1),
                {'message' : '', 'args' : ('foo', 1)}),
            (SystemExit, ('foo',),
                {'message' : 'foo', 'args' : ('foo',), 'code' : 'foo'}),
            (IOError, ('foo',),
                {'message' : 'foo', 'args' : ('foo',), 'filename' : None,
                 'errno' : None, 'strerror' : None}),
            (IOError, ('foo', 'bar'),
                {'message' : '', 'args' : ('foo', 'bar'), 'filename' : None,
                 'errno' : 'foo', 'strerror' : 'bar'}),
            (IOError, ('foo', 'bar', 'baz'),
                {'message' : '', 'args' : ('foo', 'bar'), 'filename' : 'baz',
                 'errno' : 'foo', 'strerror' : 'bar'}),
            (IOError, ('foo', 'bar', 'baz', 'quux'),
                {'message' : '', 'args' : ('foo', 'bar', 'baz', 'quux')}),
            (EnvironmentError, ('errnoStr', 'strErrorStr', 'filenameStr'),
                {'message' : '', 'args' : ('errnoStr', 'strErrorStr'),
                 'strerror' : 'strErrorStr', 'errno' : 'errnoStr',
                 'filename' : 'filenameStr'}),
            (EnvironmentError, (1, 'strErrorStr', 'filenameStr'),
                {'message' : '', 'args' : (1, 'strErrorStr'), 'errno' : 1,
                 'strerror' : 'strErrorStr', 'filename' : 'filenameStr'}),
            (SyntaxError, (), {'message' : '', 'msg' : None, 'text' : None,
                'filename' : None, 'lineno' : None, 'offset' : None,
                'print_file_and_line' : None}),
            (SyntaxError, ('msgStr',),
                {'message' : 'msgStr', 'args' : ('msgStr',), 'text' : None,
                 'print_file_and_line' : None, 'msg' : 'msgStr',
                 'filename' : None, 'lineno' : None, 'offset' : None}),
            (SyntaxError, ('msgStr', ('filenameStr', 'linenoStr', 'offsetStr',
                           'textStr')),
                {'message' : '', 'offset' : 'offsetStr', 'text' : 'textStr',
                 'args' : ('msgStr', ('filenameStr', 'linenoStr',
                                      'offsetStr', 'textStr')),
                 'print_file_and_line' : None, 'msg' : 'msgStr',
                 'filename' : 'filenameStr', 'lineno' : 'linenoStr'}),
            (SyntaxError, ('msgStr', 'filenameStr', 'linenoStr', 'offsetStr',
                           'textStr', 'print_file_and_lineStr'),
                {'message' : '', 'text' : None,
                 'args' : ('msgStr', 'filenameStr', 'linenoStr', 'offsetStr',
                           'textStr', 'print_file_and_lineStr'),
                 'print_file_and_line' : None, 'msg' : 'msgStr',
                 'filename' : None, 'lineno' : None, 'offset' : None}),
            (UnicodeError, (), {'message' : '', 'args' : (),}),
            (UnicodeEncodeError, ('ascii', u'a', 0, 1, 'ordinal not in range'),
                {'message' : '', 'args' : ('ascii', u'a', 0, 1,
                                           'ordinal not in range'),
                 'encoding' : 'ascii', 'object' : u'a',
                 'start' : 0, 'reason' : 'ordinal not in range'}),
            (UnicodeDecodeError, ('ascii', '\xff', 0, 1, 'ordinal not in range'),
                {'message' : '', 'args' : ('ascii', '\xff', 0, 1,
                                           'ordinal not in range'),
                 'encoding' : 'ascii', 'object' : '\xff',
                 'start' : 0, 'reason' : 'ordinal not in range'}),
            (UnicodeTranslateError, (u"\u3042", 0, 1, "ouch"),
                {'message' : '', 'args' : (u'\u3042', 0, 1, 'ouch'),
                 'object' : u'\u3042', 'reason' : 'ouch',
                 'start' : 0, 'end' : 1}),
        ]
        try:
            exceptionList.append(
                (WindowsError, (1, 'strErrorStr', 'filenameStr'),
                    {'message' : '', 'args' : (1, 'strErrorStr'),
                     'strerror' : 'strErrorStr', 'winerror' : 1,
                     'errno' : 22, 'filename' : 'filenameStr'})
            )
        except NameError:
            pass

        for exc, args, expected in exceptionList:
            try:
                raise exc(*args)
            except BaseException, e:
                if type(e) is not exc:
                    raise
                # Verify module name
                self.assertEqual(type(e).__module__, 'exceptions')
                # Verify no ref leaks in Exc_str()
                s = str(e)
                for checkArgName in expected:
                    self.assertEqual(repr(getattr(e, checkArgName)),
                                     repr(expected[checkArgName]),
                                     'exception "%s", attribute "%s"' %
                                      (repr(e), checkArgName))

                # test for pickling support
                for p in pickle, cPickle:
                    for protocol in range(p.HIGHEST_PROTOCOL + 1):
                        new = p.loads(p.dumps(e, protocol))
                        for checkArgName in expected:
                            got = repr(getattr(new, checkArgName))
                            want = repr(expected[checkArgName])
                            self.assertEqual(got, want,
                                             'pickled "%r", attribute "%s"' %
                                             (e, checkArgName))


    def testDeprecatedMessageAttribute(self):
        # Accessing BaseException.message and relying on its value set by
        # BaseException.__init__ triggers a deprecation warning.
        exc = BaseException("foo")
        with check_warnings(("BaseException.message has been deprecated "
                             "as of Python 2.6", DeprecationWarning)) as w:
            self.assertEqual(exc.message, "foo")
        self.assertEqual(len(w.warnings), 1)

    def testRegularMessageAttribute(self):
        # Accessing BaseException.message after explicitly setting a value
        # for it does not trigger a deprecation warning.
        exc = BaseException("foo")
        exc.message = "bar"
        with check_warnings(quiet=True) as w:
            self.assertEqual(exc.message, "bar")
        self.assertEqual(len(w.warnings), 0)
        # Deleting the message is supported, too.
        del exc.message
        with self.assertRaises(AttributeError):
            exc.message

    @ignore_deprecation_warnings
    def testPickleMessageAttribute(self):
        # Pickling with message attribute must work, as well.
        e = Exception("foo")
        f = Exception("foo")
        f.message = "bar"
        for p in pickle, cPickle:
            ep = p.loads(p.dumps(e))
            self.assertEqual(ep.message, "foo")
            fp = p.loads(p.dumps(f))
            self.assertEqual(fp.message, "bar")

    @ignore_deprecation_warnings
    def testSlicing(self):
        # Test that you can slice an exception directly instead of requiring
        # going through the 'args' attribute.
        args = (1, 2, 3)
        exc = BaseException(*args)
        self.assertEqual(exc[:], args)
        self.assertEqual(exc.args[:], args)

    def testKeywordArgs(self):
        # test that builtin exception don't take keyword args,
        # but user-defined subclasses can if they want
        self.assertRaises(TypeError, BaseException, a=1)

        class DerivedException(BaseException):
            def __init__(self, fancy_arg):
                BaseException.__init__(self)
                self.fancy_arg = fancy_arg

        x = DerivedException(fancy_arg=42)
        self.assertEqual(x.fancy_arg, 42)

    def testInfiniteRecursion(self):
        def f():
            return f()
        self.assertRaises(RuntimeError, f)

        def g():
            try:
                return g()
            except ValueError:
                return -1

        # The test prints an unraisable recursion error when
        # doing "except ValueError", this is because subclass
        # checking has recursion checking too.
        with captured_stderr():
            try:
                g()
            except RuntimeError:
                pass
            except:
                self.fail("Should have raised KeyError")
            else:
                self.fail("Should have raised KeyError")

    def testUnicodeStrUsage(self):
        # Make sure both instances and classes have a str and unicode
        # representation.
        self.assertTrue(str(Exception))
        self.assertTrue(unicode(Exception))
        self.assertTrue(str(Exception('a')))
        self.assertTrue(unicode(Exception(u'a')))
        self.assertTrue(unicode(Exception(u'\xe1')))

    def testUnicodeChangeAttributes(self):
        # See issue 7309. This was a crasher.

        u = UnicodeEncodeError('baz', u'xxxxx', 1, 5, 'foo')
        self.assertEqual(str(u), "'baz' codec can't encode characters in position 1-4: foo")
        u.end = 2
        self.assertEqual(str(u), "'baz' codec can't encode character u'\\x78' in position 1: foo")
        u.end = 5
        u.reason = 0x345345345345345345
        self.assertEqual(str(u), "'baz' codec can't encode characters in position 1-4: 965230951443685724997")
        u.encoding = 4000
        self.assertEqual(str(u), "'4000' codec can't encode characters in position 1-4: 965230951443685724997")
        u.start = 1000
        self.assertEqual(str(u), "'4000' codec can't encode characters in position 1000-4: 965230951443685724997")

        u = UnicodeDecodeError('baz', 'xxxxx', 1, 5, 'foo')
        self.assertEqual(str(u), "'baz' codec can't decode bytes in position 1-4: foo")
        u.end = 2
        self.assertEqual(str(u), "'baz' codec can't decode byte 0x78 in position 1: foo")
        u.end = 5
        u.reason = 0x345345345345345345
        self.assertEqual(str(u), "'baz' codec can't decode bytes in position 1-4: 965230951443685724997")
        u.encoding = 4000
        self.assertEqual(str(u), "'4000' codec can't decode bytes in position 1-4: 965230951443685724997")
        u.start = 1000
        self.assertEqual(str(u), "'4000' codec can't decode bytes in position 1000-4: 965230951443685724997")

        u = UnicodeTranslateError(u'xxxx', 1, 5, 'foo')
        self.assertEqual(str(u), "can't translate characters in position 1-4: foo")
        u.end = 2
        self.assertEqual(str(u), "can't translate character u'\\x78' in position 1: foo")
        u.end = 5
        u.reason = 0x345345345345345345
        self.assertEqual(str(u), "can't translate characters in position 1-4: 965230951443685724997")
        u.start = 1000
        self.assertEqual(str(u), "can't translate characters in position 1000-4: 965230951443685724997")

    def test_unicode_errors_no_object(self):
        # See issue #21134.
        klasses = UnicodeEncodeError, UnicodeDecodeError, UnicodeTranslateError
        for klass in klasses:
            self.assertEqual(str(klass.__new__(klass)), "")

    def test_badisinstance(self):
        # Bug #2542: if issubclass(e, MyException) raises an exception,
        # it should be ignored
        class Meta(type):
            def __subclasscheck__(cls, subclass):
                raise ValueError()

        class MyException(Exception):
            __metaclass__ = Meta
            pass

        with captured_stderr() as stderr:
            try:
                raise KeyError()
            except MyException, e:
                self.fail("exception should not be a MyException")
            except KeyError:
                pass
            except:
                self.fail("Should have raised KeyError")
            else:
                self.fail("Should have raised KeyError")

        with captured_stderr() as stderr:
            def g():
                try:
                    return g()
                except RuntimeError:
                    return sys.exc_info()
            e, v, tb = g()
            self.assertTrue(e is RuntimeError, e)
            self.assertIn("maximum recursion depth exceeded", str(v))

    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,)")

    def test_bad_exception_clearing(self):
        # See issue 16445: use of Py_XDECREF instead of Py_CLEAR in
        # BaseException_set_message gave a possible way to segfault the
        # interpreter.
        class Nasty(str):
            def __del__(message):
                del e.message

        e = ValueError(Nasty("msg"))
        e.args = ()
        del e.message


# Helper class used by TestSameStrAndUnicodeMsg
class ExcWithOverriddenStr(Exception):
    """Subclass of Exception that accepts a keyword 'msg' arg that is
    returned by __str__. 'msg' won't be included in self.args"""
    def __init__(self, *args, **kwargs):
        self.msg = kwargs.pop('msg') # msg should always be present
        super(ExcWithOverriddenStr, self).__init__(*args, **kwargs)
    def __str__(self):
        return self.msg


class TestSameStrAndUnicodeMsg(unittest.TestCase):
    """unicode(err) should return the same message of str(err). See #6108"""

    def check_same_msg(self, exc, msg):
        """Helper function that checks if str(exc) == unicode(exc) == msg"""
        self.assertEqual(str(exc), msg)
        self.assertEqual(str(exc), unicode(exc))

    def test_builtin_exceptions(self):
        """Check same msg for built-in exceptions"""
        # These exceptions implement a __str__ method that uses the args
        # to create a better error message. unicode(e) should return the same
        # message.
        exceptions = [
            SyntaxError('invalid syntax', ('<string>', 1, 3, '2+*3')),
            IOError(2, 'No such file or directory'),
            KeyError('both should have the same quotes'),
            UnicodeDecodeError('ascii', '\xc3\xa0', 0, 1,
                               'ordinal not in range(128)'),
            UnicodeEncodeError('ascii', u'\u1234', 0, 1,
                               'ordinal not in range(128)')
        ]
        for exception in exceptions:
            self.assertEqual(str(exception), unicode(exception))

    def test_0_args(self):
        """Check same msg for Exception with 0 args"""
        # str() and unicode() on an Exception with no args should return an
        # empty string
        self.check_same_msg(Exception(), '')

    def test_0_args_with_overridden___str__(self):
        """Check same msg for exceptions with 0 args and overridden __str__"""
        # str() and unicode() on an exception with overridden __str__ that
        # returns an ascii-only string should return the same string
        for msg in ('foo', u'foo'):
            self.check_same_msg(ExcWithOverriddenStr(msg=msg), msg)

        # if __str__ returns a non-ascii unicode string str() should fail
        # but unicode() should return the unicode string
        e = ExcWithOverriddenStr(msg=u'f\xf6\xf6') # no args
        self.assertRaises(UnicodeEncodeError, str, e)
        self.assertEqual(unicode(e), u'f\xf6\xf6')

    def test_1_arg(self):
        """Check same msg for Exceptions with 1 arg"""
        for arg in ('foo', u'foo'):
            self.check_same_msg(Exception(arg), arg)

        # if __str__ is not overridden and self.args[0] is a non-ascii unicode
        # string, str() should try to return str(self.args[0]) and fail.
        # unicode() should return unicode(self.args[0]) and succeed.
        e = Exception(u'f\xf6\xf6')
        self.assertRaises(UnicodeEncodeError, str, e)
        self.assertEqual(unicode(e), u'f\xf6\xf6')

    def test_1_arg_with_overridden___str__(self):
        """Check same msg for exceptions with overridden __str__ and 1 arg"""
        # when __str__ is overridden and __unicode__ is not implemented
        # unicode(e) returns the same as unicode(e.__str__()).
        for msg in ('foo', u'foo'):
            self.check_same_msg(ExcWithOverriddenStr('arg', msg=msg), msg)

        # if __str__ returns a non-ascii unicode string, str() should fail
        # but unicode() should succeed.
        e = ExcWithOverriddenStr('arg', msg=u'f\xf6\xf6') # 1 arg
        self.assertRaises(UnicodeEncodeError, str, e)
        self.assertEqual(unicode(e), u'f\xf6\xf6')

    def test_many_args(self):
        """Check same msg for Exceptions with many args"""
        argslist = [
            (3, 'foo'),
            (1, u'foo', 'bar'),
            (4, u'f\xf6\xf6', u'bar', 'baz')
        ]
        # both str() and unicode() should return a repr() of the args
        for args in argslist:
            self.check_same_msg(Exception(*args), repr(args))

    def test_many_args_with_overridden___str__(self):
        """Check same msg for exceptions with overridden __str__ and many args"""
        # if __str__ returns an ascii string / ascii unicode string
        # both str() and unicode() should succeed
        for msg in ('foo', u'foo'):
            e = ExcWithOverriddenStr('arg1', u'arg2', u'f\xf6\xf6', msg=msg)
            self.check_same_msg(e, msg)

        # if __str__ returns a non-ascii unicode string, str() should fail
        # but unicode() should succeed
        e = ExcWithOverriddenStr('arg1', u'f\xf6\xf6', u'arg3', # 3 args
                                 msg=u'f\xf6\xf6')
        self.assertRaises(UnicodeEncodeError, str, e)
        self.assertEqual(unicode(e), u'f\xf6\xf6')

    @cpython_only
    def test_exception_with_doc(self):
        import _testcapi
        doc2 = "This is a test docstring."
        doc4 = "This is another test docstring."

        self.assertRaises(SystemError, _testcapi.make_exception_with_doc,
                          "error1")

        # test basic usage of PyErr_NewException
        error1 = _testcapi.make_exception_with_doc("_testcapi.error1")
        self.assertIs(type(error1), type)
        self.assertTrue(issubclass(error1, Exception))
        self.assertIsNone(error1.__doc__)

        # test with given docstring
        error2 = _testcapi.make_exception_with_doc("_testcapi.error2", doc2)
        self.assertEqual(error2.__doc__, doc2)

        # test with explicit base (without docstring)
        error3 = _testcapi.make_exception_with_doc("_testcapi.error3",
                                                   base=error2)
        self.assertTrue(issubclass(error3, error2))

        # test with explicit base tuple
        class C(object):
            pass
        error4 = _testcapi.make_exception_with_doc("_testcapi.error4", doc4,
                                                   (error3, C))
        self.assertTrue(issubclass(error4, error3))
        self.assertTrue(issubclass(error4, C))
        self.assertEqual(error4.__doc__, doc4)

        # test with explicit dictionary
        error5 = _testcapi.make_exception_with_doc("_testcapi.error5", "",
                                                   error4, {'a': 1})
        self.assertTrue(issubclass(error5, error4))
        self.assertEqual(error5.a, 1)
        self.assertEqual(error5.__doc__, "")

    def test_unraisable(self):
        # Issue #22836: PyErr_WriteUnraisable() should give sensible reports
        class BrokenDel:
            def __del__(self):
                exc = ValueError("del is broken")
                # In Python 3, the following line would be in the report:
                raise exc

        class BrokenRepr(BrokenDel):
            def __repr__(self):
                raise AttributeError("repr() is broken")

        class BrokenExceptionDel:
            def __del__(self):
                exc = BrokenStrException()
                # In Python 3, the following line would be in the report:
                raise exc

        for test_class in (BrokenDel, BrokenRepr, BrokenExceptionDel):
            obj = test_class()
            with captured_stderr() as stderr:
                del obj
            report = stderr.getvalue()
            self.assertRegexpMatches(report, "Exception.* ignored")
            if test_class is BrokenRepr:
                self.assertIn("<object repr() failed>", report)
            else:
                self.assertIn("__del__", report)
            if test_class is BrokenExceptionDel:
                self.assertIn("BrokenStrException", report)
                self.assertIn("<exception repr() failed>", report)
            else:
                self.assertIn("ValueError", report)
                self.assertIn("del is broken", report)
            self.assertTrue(report.endswith("\n"))

    def test_unhandled(self):
        # Check for sensible reporting of unhandled exceptions
        for exc_type in (ValueError, BrokenStrException):
            try:
                exc = exc_type("test message")
                # The following line is included in the traceback report:
                raise exc
            except exc_type:
                with captured_stderr() as stderr:
                    sys.__excepthook__(*sys.exc_info())
            report = stderr.getvalue()
            self.assertIn("test_exceptions.py", report)
            self.assertIn("raise exc", report)
            self.assertIn(exc_type.__name__, report)
            if exc_type is BrokenStrException:
                self.assertIn("<exception str() failed>", report)
            else:
                self.assertIn("test message", report)
            self.assertTrue(report.endswith("\n"))


def test_main():
    run_unittest(ExceptionTests, TestSameStrAndUnicodeMsg)

if __name__ == '__main__':
    test_main()
