diff options
Diffstat (limited to 'Lib/test/test_exceptions.py')
| -rw-r--r-- | Lib/test/test_exceptions.py | 104 | 
1 files changed, 85 insertions, 19 deletions
| diff --git a/Lib/test/test_exceptions.py b/Lib/test/test_exceptions.py index 8d11d90..d954302 100644 --- a/Lib/test/test_exceptions.py +++ b/Lib/test/test_exceptions.py @@ -8,8 +8,8 @@ import weakref  import errno  from test.support import (TESTFN, captured_output, check_impl_detail, -                          check_warnings, cpython_only, gc_collect, -                          no_tracing, run_unittest, unlink) +                          check_warnings, cpython_only, gc_collect, run_unittest, +                          no_tracing, unlink, import_module)  class NaiveException(Exception):      def __init__(self, x): @@ -230,6 +230,7 @@ class ExceptionTests(unittest.TestCase):              self.assertEqual(w.winerror, 3)              self.assertEqual(w.strerror, 'foo')              self.assertEqual(w.filename, 'bar') +            self.assertEqual(w.filename2, None)              self.assertEqual(str(w), "[WinError 3] foo: 'bar'")              # Unknown win error becomes EINVAL (22)              w = OSError(0, 'foo', None, 1001) @@ -237,6 +238,7 @@ class ExceptionTests(unittest.TestCase):              self.assertEqual(w.winerror, 1001)              self.assertEqual(w.strerror, 'foo')              self.assertEqual(w.filename, None) +            self.assertEqual(w.filename2, None)              self.assertEqual(str(w), "[WinError 1001] foo")              # Non-numeric "errno"              w = OSError('bar', 'foo') @@ -244,6 +246,17 @@ class ExceptionTests(unittest.TestCase):              self.assertEqual(w.winerror, None)              self.assertEqual(w.strerror, 'foo')              self.assertEqual(w.filename, None) +            self.assertEqual(w.filename2, None) + +    @unittest.skipUnless(sys.platform == 'win32', +                         'test specific to Windows') +    def test_windows_message(self): +        """Should fill in unknown error code in Windows error message""" +        ctypes = import_module('ctypes') +        # this error code has no message, Python formats it as hexadecimal +        code = 3765269347 +        with self.assertRaisesRegex(OSError, 'Windows Error 0x%x' % code): +            ctypes.pythonapi.PyErr_SetFromWindowsErr(code)      def testAttributes(self):          # test that exception attributes are happy @@ -257,24 +270,27 @@ class ExceptionTests(unittest.TestCase):                  {'args' : ('foo', 1)}),              (SystemExit, ('foo',),                  {'args' : ('foo',), 'code' : 'foo'}), -            (IOError, ('foo',), -                {'args' : ('foo',), 'filename' : None, +            (OSError, ('foo',), +                {'args' : ('foo',), 'filename' : None, 'filename2' : None,                   'errno' : None, 'strerror' : None}), -            (IOError, ('foo', 'bar'), -                {'args' : ('foo', 'bar'), 'filename' : None, +            (OSError, ('foo', 'bar'), +                {'args' : ('foo', 'bar'), +                 'filename' : None, 'filename2' : None,                   'errno' : 'foo', 'strerror' : 'bar'}), -            (IOError, ('foo', 'bar', 'baz'), -                {'args' : ('foo', 'bar'), 'filename' : 'baz', +            (OSError, ('foo', 'bar', 'baz'), +                {'args' : ('foo', 'bar'), +                 'filename' : 'baz', 'filename2' : None,                   'errno' : 'foo', 'strerror' : 'bar'}), -            (IOError, ('foo', 'bar', 'baz', 'quux'), -                {'args' : ('foo', 'bar', 'baz', 'quux')}), -            (EnvironmentError, ('errnoStr', 'strErrorStr', 'filenameStr'), +            (OSError, ('foo', 'bar', 'baz', None, 'quux'), +                {'args' : ('foo', 'bar'), 'filename' : 'baz', 'filename2': 'quux'}), +            (OSError, ('errnoStr', 'strErrorStr', 'filenameStr'),                  {'args' : ('errnoStr', 'strErrorStr'),                   'strerror' : 'strErrorStr', 'errno' : 'errnoStr',                   'filename' : 'filenameStr'}), -            (EnvironmentError, (1, 'strErrorStr', 'filenameStr'), +            (OSError, (1, 'strErrorStr', 'filenameStr'),                  {'args' : (1, 'strErrorStr'), 'errno' : 1, -                 'strerror' : 'strErrorStr', 'filename' : 'filenameStr'}), +                 'strerror' : 'strErrorStr', +                 'filename' : 'filenameStr', 'filename2' : None}),              (SyntaxError, (), {'msg' : None, 'text' : None,                  'filename' : None, 'lineno' : None, 'offset' : None,                  'print_file_and_line' : None}), @@ -330,7 +346,8 @@ class ExceptionTests(unittest.TestCase):                  (WindowsError, (1, 'strErrorStr', 'filenameStr'),                      {'args' : (1, 'strErrorStr'),                       'strerror' : 'strErrorStr', 'winerror' : None, -                     'errno' : 1, 'filename' : 'filenameStr'}) +                     'errno' : 1, +                     'filename' : 'filenameStr', 'filename2' : None})              )          except NameError:              pass @@ -422,7 +439,7 @@ class ExceptionTests(unittest.TestCase):          self.assertIsNone(e.__context__)          self.assertIsNone(e.__cause__) -        class MyException(EnvironmentError): +        class MyException(OSError):              pass          e = MyException() @@ -661,6 +678,52 @@ class ExceptionTests(unittest.TestCase):              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) @@ -763,7 +826,7 @@ class ExceptionTests(unittest.TestCase):              pass          self.assertEqual(e, (None, None, None)) -    def testUnicodeChangeAttributes(self): +    def test_unicode_change_attributes(self):          # See issue 7309. This was a crasher.          u = UnicodeEncodeError('baz', 'xxxxx', 1, 5, 'foo') @@ -800,6 +863,12 @@ class ExceptionTests(unittest.TestCase):          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)), "") +      @no_tracing      def test_badisinstance(self):          # Bug #2542: if issubclass(e, MyException) raises an exception, @@ -968,8 +1037,5 @@ class ImportErrorTests(unittest.TestCase):              self.assertEqual(str(arg), str(exc)) -def test_main(): -    run_unittest(ExceptionTests, ImportErrorTests) -  if __name__ == '__main__':      unittest.main() | 
