diff options
Diffstat (limited to 'Lib/test/test_exceptions.py')
| -rw-r--r-- | Lib/test/test_exceptions.py | 87 |
1 files changed, 73 insertions, 14 deletions
diff --git a/Lib/test/test_exceptions.py b/Lib/test/test_exceptions.py index 8d11d90..80d4f1a 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): @@ -245,6 +245,16 @@ class ExceptionTests(unittest.TestCase): self.assertEqual(w.strerror, 'foo') self.assertEqual(w.filename, 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,22 +267,22 @@ class ExceptionTests(unittest.TestCase): {'args' : ('foo', 1)}), (SystemExit, ('foo',), {'args' : ('foo',), 'code' : 'foo'}), - (IOError, ('foo',), + (OSError, ('foo',), {'args' : ('foo',), 'filename' : None, 'errno' : None, 'strerror' : None}), - (IOError, ('foo', 'bar'), + (OSError, ('foo', 'bar'), {'args' : ('foo', 'bar'), 'filename' : None, 'errno' : 'foo', 'strerror' : 'bar'}), - (IOError, ('foo', 'bar', 'baz'), + (OSError, ('foo', 'bar', 'baz'), {'args' : ('foo', 'bar'), 'filename' : 'baz', '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'}), (SyntaxError, (), {'msg' : None, 'text' : None, @@ -422,7 +432,7 @@ class ExceptionTests(unittest.TestCase): self.assertIsNone(e.__context__) self.assertIsNone(e.__cause__) - class MyException(EnvironmentError): + class MyException(OSError): pass e = MyException() @@ -661,6 +671,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 +819,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 +856,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 +1030,5 @@ class ImportErrorTests(unittest.TestCase): self.assertEqual(str(arg), str(exc)) -def test_main(): - run_unittest(ExceptionTests, ImportErrorTests) - if __name__ == '__main__': unittest.main() |
