blob: bc8944dc2dd5818b9e2a4e0fa1202c0e0dacffff [file] [log] [blame]
Guido van Rossum3bead091992-01-27 17:00:37 +00001# Python test set -- part 5, built-in exceptions
2
Tim Peters80dc76e2006-06-07 06:57:51 +00003import os
4import sys
Georg Brandlcdcede62006-05-30 08:47:19 +00005import unittest
Tim Peters80dc76e2006-06-07 06:57:51 +00006import pickle, cPickle
7
Martin Panteref85a1a2016-02-28 00:18:43 +00008from test.test_support import (TESTFN, unlink, run_unittest, captured_stderr,
Benjamin Peterson8eeb1dc2010-06-28 15:36:40 +00009 check_warnings, cpython_only)
Ezio Melotti1f517e12010-02-02 17:34:37 +000010from test.test_pep352 import ignore_deprecation_warnings
Guido van Rossum83b120d2001-08-23 03:23:03 +000011
Martin Panteref85a1a2016-02-28 00:18:43 +000012class BrokenStrException(Exception):
13 def __str__(self):
14 raise Exception("str() is broken")
15 __repr__ = __str__ # Python 2's PyErr_WriteUnraisable() uses repr()
16
Guido van Rossum3bead091992-01-27 17:00:37 +000017# XXX This is not really enough, each *operation* should be tested!
18
Georg Brandlcdcede62006-05-30 08:47:19 +000019class ExceptionTests(unittest.TestCase):
Barry Warsawb9c1d3d2001-08-13 23:07:00 +000020
Georg Brandlcdcede62006-05-30 08:47:19 +000021 def testReload(self):
22 # Reloading the built-in exceptions module failed prior to Py2.2, while it
23 # should act the same as reloading built-in sys.
24 try:
Ezio Melotti1f517e12010-02-02 17:34:37 +000025 from imp import reload
Georg Brandlcdcede62006-05-30 08:47:19 +000026 import exceptions
27 reload(exceptions)
28 except ImportError, e:
29 self.fail("reloading exceptions: %s" % e)
Jeremy Hylton56c807d2000-06-20 18:52:57 +000030
Georg Brandlcdcede62006-05-30 08:47:19 +000031 def raise_catch(self, exc, excname):
32 try:
33 raise exc, "spam"
34 except exc, err:
35 buf1 = str(err)
36 try:
37 raise exc("spam")
38 except exc, err:
39 buf2 = str(err)
Ezio Melotti2623a372010-11-21 13:34:58 +000040 self.assertEqual(buf1, buf2)
41 self.assertEqual(exc.__name__, excname)
Guido van Rossum3bead091992-01-27 17:00:37 +000042
Georg Brandlcdcede62006-05-30 08:47:19 +000043 def testRaising(self):
Tim Petersdd55b0a2006-05-30 23:28:02 +000044 self.raise_catch(AttributeError, "AttributeError")
Georg Brandlcdcede62006-05-30 08:47:19 +000045 self.assertRaises(AttributeError, getattr, sys, "undefined_attribute")
Guido van Rossum3bead091992-01-27 17:00:37 +000046
Georg Brandlcdcede62006-05-30 08:47:19 +000047 self.raise_catch(EOFError, "EOFError")
48 fp = open(TESTFN, 'w')
49 fp.close()
50 fp = open(TESTFN, 'r')
51 savestdin = sys.stdin
52 try:
53 try:
54 sys.stdin = fp
55 x = raw_input()
56 except EOFError:
57 pass
58 finally:
59 sys.stdin = savestdin
60 fp.close()
61 unlink(TESTFN)
Guido van Rossum3bead091992-01-27 17:00:37 +000062
Georg Brandlcdcede62006-05-30 08:47:19 +000063 self.raise_catch(IOError, "IOError")
64 self.assertRaises(IOError, open, 'this file does not exist', 'r')
Guido van Rossum3bead091992-01-27 17:00:37 +000065
Georg Brandlcdcede62006-05-30 08:47:19 +000066 self.raise_catch(ImportError, "ImportError")
67 self.assertRaises(ImportError, __import__, "undefined_module")
Guido van Rossum3bead091992-01-27 17:00:37 +000068
Georg Brandlcdcede62006-05-30 08:47:19 +000069 self.raise_catch(IndexError, "IndexError")
70 x = []
71 self.assertRaises(IndexError, x.__getitem__, 10)
Guido van Rossum3bead091992-01-27 17:00:37 +000072
Georg Brandlcdcede62006-05-30 08:47:19 +000073 self.raise_catch(KeyError, "KeyError")
74 x = {}
75 self.assertRaises(KeyError, x.__getitem__, 'key')
Guido van Rossum3bead091992-01-27 17:00:37 +000076
Georg Brandlcdcede62006-05-30 08:47:19 +000077 self.raise_catch(KeyboardInterrupt, "KeyboardInterrupt")
Guido van Rossum3bead091992-01-27 17:00:37 +000078
Georg Brandlcdcede62006-05-30 08:47:19 +000079 self.raise_catch(MemoryError, "MemoryError")
Guido van Rossum3bead091992-01-27 17:00:37 +000080
Georg Brandlcdcede62006-05-30 08:47:19 +000081 self.raise_catch(NameError, "NameError")
82 try: x = undefined_variable
83 except NameError: pass
Guido van Rossum3bead091992-01-27 17:00:37 +000084
Georg Brandlcdcede62006-05-30 08:47:19 +000085 self.raise_catch(OverflowError, "OverflowError")
86 x = 1
87 for dummy in range(128):
88 x += x # this simply shouldn't blow up
Guido van Rossum3bead091992-01-27 17:00:37 +000089
Georg Brandlcdcede62006-05-30 08:47:19 +000090 self.raise_catch(RuntimeError, "RuntimeError")
Guido van Rossum3bead091992-01-27 17:00:37 +000091
Georg Brandlcdcede62006-05-30 08:47:19 +000092 self.raise_catch(SyntaxError, "SyntaxError")
93 try: exec '/\n'
94 except SyntaxError: pass
Guido van Rossum3bead091992-01-27 17:00:37 +000095
Georg Brandlcdcede62006-05-30 08:47:19 +000096 self.raise_catch(IndentationError, "IndentationError")
Fred Drake72e48bd2000-09-08 16:32:34 +000097
Georg Brandlcdcede62006-05-30 08:47:19 +000098 self.raise_catch(TabError, "TabError")
99 # can only be tested under -tt, and is the only test for -tt
Serhiy Storchaka5312a7f2015-01-31 11:27:06 +0200100 #try: compile("try:\n\t1.0/0.0\n \t1.0/0.0\nfinally:\n pass\n", '<string>', 'exec')
Georg Brandlcdcede62006-05-30 08:47:19 +0000101 #except TabError: pass
102 #else: self.fail("TabError not raised")
Fred Drake72e48bd2000-09-08 16:32:34 +0000103
Georg Brandlcdcede62006-05-30 08:47:19 +0000104 self.raise_catch(SystemError, "SystemError")
Fred Drake72e48bd2000-09-08 16:32:34 +0000105
Georg Brandlcdcede62006-05-30 08:47:19 +0000106 self.raise_catch(SystemExit, "SystemExit")
107 self.assertRaises(SystemExit, sys.exit, 0)
Fred Drake85f36392000-07-11 17:53:00 +0000108
Georg Brandlcdcede62006-05-30 08:47:19 +0000109 self.raise_catch(TypeError, "TypeError")
110 try: [] + ()
111 except TypeError: pass
Fred Drake85f36392000-07-11 17:53:00 +0000112
Georg Brandlcdcede62006-05-30 08:47:19 +0000113 self.raise_catch(ValueError, "ValueError")
114 self.assertRaises(ValueError, chr, 10000)
Guido van Rossum3bead091992-01-27 17:00:37 +0000115
Georg Brandlcdcede62006-05-30 08:47:19 +0000116 self.raise_catch(ZeroDivisionError, "ZeroDivisionError")
Ezio Melotti1f517e12010-02-02 17:34:37 +0000117 try: x = 1 // 0
Georg Brandlcdcede62006-05-30 08:47:19 +0000118 except ZeroDivisionError: pass
Guido van Rossum3bead091992-01-27 17:00:37 +0000119
Georg Brandlcdcede62006-05-30 08:47:19 +0000120 self.raise_catch(Exception, "Exception")
Ezio Melotti1f517e12010-02-02 17:34:37 +0000121 try: x = 1 // 0
Georg Brandlcdcede62006-05-30 08:47:19 +0000122 except Exception, e: pass
Guido van Rossum3bead091992-01-27 17:00:37 +0000123
Georg Brandlcdcede62006-05-30 08:47:19 +0000124 def testSyntaxErrorMessage(self):
Neal Norwitze152aab2006-06-02 04:45:53 +0000125 # make sure the right exception message is raised for each of
126 # these code fragments
Guido van Rossum3bead091992-01-27 17:00:37 +0000127
Georg Brandlcdcede62006-05-30 08:47:19 +0000128 def ckmsg(src, msg):
129 try:
130 compile(src, '<fragment>', 'exec')
131 except SyntaxError, e:
132 if e.msg != msg:
133 self.fail("expected %s, got %s" % (msg, e.msg))
134 else:
135 self.fail("failed to get expected SyntaxError")
Guido van Rossum3bead091992-01-27 17:00:37 +0000136
Georg Brandlcdcede62006-05-30 08:47:19 +0000137 s = '''while 1:
138 try:
139 pass
140 finally:
141 continue'''
Barry Warsaw992cb8a2000-05-25 23:16:54 +0000142
Georg Brandlcdcede62006-05-30 08:47:19 +0000143 if not sys.platform.startswith('java'):
144 ckmsg(s, "'continue' not supported inside 'finally' clause")
Jeremy Hyltonede049b2001-09-26 20:01:13 +0000145
Georg Brandlcdcede62006-05-30 08:47:19 +0000146 s = '''if 1:
147 try:
148 continue
149 except:
150 pass'''
Jeremy Hyltonede049b2001-09-26 20:01:13 +0000151
Georg Brandlcdcede62006-05-30 08:47:19 +0000152 ckmsg(s, "'continue' not properly in loop")
153 ckmsg("continue\n", "'continue' not properly in loop")
Jeremy Hyltonede049b2001-09-26 20:01:13 +0000154
Benjamin Peterson8eeb1dc2010-06-28 15:36:40 +0000155 @cpython_only
Georg Brandlcdcede62006-05-30 08:47:19 +0000156 def testSettingException(self):
Neal Norwitze152aab2006-06-02 04:45:53 +0000157 # test that setting an exception at the C level works even if the
158 # exception object can't be constructed.
Finn Bockaa3dc452001-12-08 10:15:48 +0000159
Georg Brandlcdcede62006-05-30 08:47:19 +0000160 class BadException:
161 def __init__(self_):
162 raise RuntimeError, "can't instantiate BadException"
Jeremy Hyltonede049b2001-09-26 20:01:13 +0000163
Georg Brandlcdcede62006-05-30 08:47:19 +0000164 def test_capi1():
165 import _testcapi
166 try:
167 _testcapi.raise_exception(BadException, 1)
168 except TypeError, err:
169 exc, err, tb = sys.exc_info()
170 co = tb.tb_frame.f_code
Ezio Melotti2623a372010-11-21 13:34:58 +0000171 self.assertEqual(co.co_name, "test_capi1")
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000172 self.assertTrue(co.co_filename.endswith('test_exceptions'+os.extsep+'py'))
Georg Brandlcdcede62006-05-30 08:47:19 +0000173 else:
174 self.fail("Expected exception")
Richard Jones7b9558d2006-05-27 12:29:24 +0000175
Georg Brandlcdcede62006-05-30 08:47:19 +0000176 def test_capi2():
177 import _testcapi
178 try:
179 _testcapi.raise_exception(BadException, 0)
180 except RuntimeError, err:
181 exc, err, tb = sys.exc_info()
182 co = tb.tb_frame.f_code
Ezio Melotti2623a372010-11-21 13:34:58 +0000183 self.assertEqual(co.co_name, "__init__")
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000184 self.assertTrue(co.co_filename.endswith('test_exceptions'+os.extsep+'py'))
Georg Brandlcdcede62006-05-30 08:47:19 +0000185 co2 = tb.tb_frame.f_back.f_code
Ezio Melotti2623a372010-11-21 13:34:58 +0000186 self.assertEqual(co2.co_name, "test_capi2")
Georg Brandlcdcede62006-05-30 08:47:19 +0000187 else:
188 self.fail("Expected exception")
Richard Jones7b9558d2006-05-27 12:29:24 +0000189
Georg Brandlcdcede62006-05-30 08:47:19 +0000190 if not sys.platform.startswith('java'):
191 test_capi1()
192 test_capi2()
Georg Brandl05f97bf2006-05-30 07:13:29 +0000193
Thomas Hellerdf08f0b2006-10-27 18:31:36 +0000194 def test_WindowsError(self):
195 try:
196 WindowsError
197 except NameError:
198 pass
199 else:
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000200 self.assertEqual(str(WindowsError(1001)),
Thomas Hellerdf08f0b2006-10-27 18:31:36 +0000201 "1001")
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000202 self.assertEqual(str(WindowsError(1001, "message")),
Thomas Hellerdf08f0b2006-10-27 18:31:36 +0000203 "[Error 1001] message")
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000204 self.assertEqual(WindowsError(1001, "message").errno, 22)
205 self.assertEqual(WindowsError(1001, "message").winerror, 1001)
Thomas Hellerdf08f0b2006-10-27 18:31:36 +0000206
Ezio Melotti1f517e12010-02-02 17:34:37 +0000207 @ignore_deprecation_warnings
Georg Brandlcdcede62006-05-30 08:47:19 +0000208 def testAttributes(self):
Neal Norwitze152aab2006-06-02 04:45:53 +0000209 # test that exception attributes are happy
Tim Petersdd55b0a2006-05-30 23:28:02 +0000210
Georg Brandlcdcede62006-05-30 08:47:19 +0000211 exceptionList = [
Georg Brandle08940e2006-06-01 13:00:49 +0000212 (BaseException, (), {'message' : '', 'args' : ()}),
213 (BaseException, (1, ), {'message' : 1, 'args' : (1,)}),
214 (BaseException, ('foo',),
215 {'message' : 'foo', 'args' : ('foo',)}),
216 (BaseException, ('foo', 1),
217 {'message' : '', 'args' : ('foo', 1)}),
218 (SystemExit, ('foo',),
219 {'message' : 'foo', 'args' : ('foo',), 'code' : 'foo'}),
220 (IOError, ('foo',),
Georg Brandl3267d282006-09-30 09:03:42 +0000221 {'message' : 'foo', 'args' : ('foo',), 'filename' : None,
222 'errno' : None, 'strerror' : None}),
Georg Brandle08940e2006-06-01 13:00:49 +0000223 (IOError, ('foo', 'bar'),
Georg Brandl3267d282006-09-30 09:03:42 +0000224 {'message' : '', 'args' : ('foo', 'bar'), 'filename' : None,
225 'errno' : 'foo', 'strerror' : 'bar'}),
Georg Brandle08940e2006-06-01 13:00:49 +0000226 (IOError, ('foo', 'bar', 'baz'),
Georg Brandl3267d282006-09-30 09:03:42 +0000227 {'message' : '', 'args' : ('foo', 'bar'), 'filename' : 'baz',
228 'errno' : 'foo', 'strerror' : 'bar'}),
229 (IOError, ('foo', 'bar', 'baz', 'quux'),
230 {'message' : '', 'args' : ('foo', 'bar', 'baz', 'quux')}),
Georg Brandle08940e2006-06-01 13:00:49 +0000231 (EnvironmentError, ('errnoStr', 'strErrorStr', 'filenameStr'),
232 {'message' : '', 'args' : ('errnoStr', 'strErrorStr'),
233 'strerror' : 'strErrorStr', 'errno' : 'errnoStr',
234 'filename' : 'filenameStr'}),
235 (EnvironmentError, (1, 'strErrorStr', 'filenameStr'),
236 {'message' : '', 'args' : (1, 'strErrorStr'), 'errno' : 1,
237 'strerror' : 'strErrorStr', 'filename' : 'filenameStr'}),
Brett Cannonf8267df2007-02-28 18:15:00 +0000238 (SyntaxError, (), {'message' : '', 'msg' : None, 'text' : None,
239 'filename' : None, 'lineno' : None, 'offset' : None,
240 'print_file_and_line' : None}),
Georg Brandle08940e2006-06-01 13:00:49 +0000241 (SyntaxError, ('msgStr',),
242 {'message' : 'msgStr', 'args' : ('msgStr',), 'text' : None,
243 'print_file_and_line' : None, 'msg' : 'msgStr',
244 'filename' : None, 'lineno' : None, 'offset' : None}),
245 (SyntaxError, ('msgStr', ('filenameStr', 'linenoStr', 'offsetStr',
246 'textStr')),
247 {'message' : '', 'offset' : 'offsetStr', 'text' : 'textStr',
248 'args' : ('msgStr', ('filenameStr', 'linenoStr',
249 'offsetStr', 'textStr')),
250 'print_file_and_line' : None, 'msg' : 'msgStr',
251 'filename' : 'filenameStr', 'lineno' : 'linenoStr'}),
252 (SyntaxError, ('msgStr', 'filenameStr', 'linenoStr', 'offsetStr',
253 'textStr', 'print_file_and_lineStr'),
254 {'message' : '', 'text' : None,
255 'args' : ('msgStr', 'filenameStr', 'linenoStr', 'offsetStr',
256 'textStr', 'print_file_and_lineStr'),
257 'print_file_and_line' : None, 'msg' : 'msgStr',
258 'filename' : None, 'lineno' : None, 'offset' : None}),
259 (UnicodeError, (), {'message' : '', 'args' : (),}),
Georg Brandl38f62372006-09-06 06:50:05 +0000260 (UnicodeEncodeError, ('ascii', u'a', 0, 1, 'ordinal not in range'),
261 {'message' : '', 'args' : ('ascii', u'a', 0, 1,
262 'ordinal not in range'),
263 'encoding' : 'ascii', 'object' : u'a',
264 'start' : 0, 'reason' : 'ordinal not in range'}),
265 (UnicodeDecodeError, ('ascii', '\xff', 0, 1, 'ordinal not in range'),
Georg Brandle08940e2006-06-01 13:00:49 +0000266 {'message' : '', 'args' : ('ascii', '\xff', 0, 1,
Georg Brandl38f62372006-09-06 06:50:05 +0000267 'ordinal not in range'),
Georg Brandle08940e2006-06-01 13:00:49 +0000268 'encoding' : 'ascii', 'object' : '\xff',
Georg Brandl38f62372006-09-06 06:50:05 +0000269 'start' : 0, 'reason' : 'ordinal not in range'}),
Georg Brandle08940e2006-06-01 13:00:49 +0000270 (UnicodeTranslateError, (u"\u3042", 0, 1, "ouch"),
271 {'message' : '', 'args' : (u'\u3042', 0, 1, 'ouch'),
272 'object' : u'\u3042', 'reason' : 'ouch',
273 'start' : 0, 'end' : 1}),
274 ]
Georg Brandlcdcede62006-05-30 08:47:19 +0000275 try:
276 exceptionList.append(
Georg Brandle08940e2006-06-01 13:00:49 +0000277 (WindowsError, (1, 'strErrorStr', 'filenameStr'),
278 {'message' : '', 'args' : (1, 'strErrorStr'),
279 'strerror' : 'strErrorStr', 'winerror' : 1,
280 'errno' : 22, 'filename' : 'filenameStr'})
281 )
Tim Peters80dc76e2006-06-07 06:57:51 +0000282 except NameError:
283 pass
Georg Brandlcdcede62006-05-30 08:47:19 +0000284
Ezio Melotti1f517e12010-02-02 17:34:37 +0000285 for exc, args, expected in exceptionList:
286 try:
287 raise exc(*args)
288 except BaseException, e:
289 if type(e) is not exc:
290 raise
291 # Verify module name
Ezio Melotti2623a372010-11-21 13:34:58 +0000292 self.assertEqual(type(e).__module__, 'exceptions')
Ezio Melotti1f517e12010-02-02 17:34:37 +0000293 # Verify no ref leaks in Exc_str()
294 s = str(e)
295 for checkArgName in expected:
Ezio Melotti2623a372010-11-21 13:34:58 +0000296 self.assertEqual(repr(getattr(e, checkArgName)),
297 repr(expected[checkArgName]),
298 'exception "%s", attribute "%s"' %
299 (repr(e), checkArgName))
Tim Petersdd55b0a2006-05-30 23:28:02 +0000300
Ezio Melotti1f517e12010-02-02 17:34:37 +0000301 # test for pickling support
302 for p in pickle, cPickle:
303 for protocol in range(p.HIGHEST_PROTOCOL + 1):
304 new = p.loads(p.dumps(e, protocol))
305 for checkArgName in expected:
306 got = repr(getattr(new, checkArgName))
307 want = repr(expected[checkArgName])
Ezio Melotti2623a372010-11-21 13:34:58 +0000308 self.assertEqual(got, want,
309 'pickled "%r", attribute "%s"' %
310 (e, checkArgName))
Georg Brandlcdcede62006-05-30 08:47:19 +0000311
Georg Brandl0674d3f2009-09-16 20:30:09 +0000312
313 def testDeprecatedMessageAttribute(self):
314 # Accessing BaseException.message and relying on its value set by
315 # BaseException.__init__ triggers a deprecation warning.
316 exc = BaseException("foo")
Florent Xicluna6257a7b2010-03-31 22:01:03 +0000317 with check_warnings(("BaseException.message has been deprecated "
318 "as of Python 2.6", DeprecationWarning)) as w:
319 self.assertEqual(exc.message, "foo")
320 self.assertEqual(len(w.warnings), 1)
Georg Brandl0674d3f2009-09-16 20:30:09 +0000321
322 def testRegularMessageAttribute(self):
323 # Accessing BaseException.message after explicitly setting a value
324 # for it does not trigger a deprecation warning.
325 exc = BaseException("foo")
326 exc.message = "bar"
Florent Xicluna6257a7b2010-03-31 22:01:03 +0000327 with check_warnings(quiet=True) as w:
328 self.assertEqual(exc.message, "bar")
329 self.assertEqual(len(w.warnings), 0)
Georg Brandl0674d3f2009-09-16 20:30:09 +0000330 # Deleting the message is supported, too.
331 del exc.message
332 with self.assertRaises(AttributeError):
333 exc.message
334
Ezio Melotti1f517e12010-02-02 17:34:37 +0000335 @ignore_deprecation_warnings
Georg Brandl0674d3f2009-09-16 20:30:09 +0000336 def testPickleMessageAttribute(self):
337 # Pickling with message attribute must work, as well.
338 e = Exception("foo")
339 f = Exception("foo")
340 f.message = "bar"
341 for p in pickle, cPickle:
342 ep = p.loads(p.dumps(e))
Ezio Melotti1f517e12010-02-02 17:34:37 +0000343 self.assertEqual(ep.message, "foo")
Georg Brandl0674d3f2009-09-16 20:30:09 +0000344 fp = p.loads(p.dumps(f))
345 self.assertEqual(fp.message, "bar")
346
Ezio Melotti1f517e12010-02-02 17:34:37 +0000347 @ignore_deprecation_warnings
Brett Cannone05e6b02007-01-29 04:41:44 +0000348 def testSlicing(self):
349 # Test that you can slice an exception directly instead of requiring
350 # going through the 'args' attribute.
351 args = (1, 2, 3)
352 exc = BaseException(*args)
Senthil Kumarance8e33a2010-01-08 19:04:16 +0000353 self.assertEqual(exc[:], args)
Ezio Melotti1f517e12010-02-02 17:34:37 +0000354 self.assertEqual(exc.args[:], args)
Brett Cannone05e6b02007-01-29 04:41:44 +0000355
Georg Brandlcdcede62006-05-30 08:47:19 +0000356 def testKeywordArgs(self):
Neal Norwitze152aab2006-06-02 04:45:53 +0000357 # test that builtin exception don't take keyword args,
358 # but user-defined subclasses can if they want
Georg Brandlcdcede62006-05-30 08:47:19 +0000359 self.assertRaises(TypeError, BaseException, a=1)
Georg Brandle08940e2006-06-01 13:00:49 +0000360
Georg Brandlcdcede62006-05-30 08:47:19 +0000361 class DerivedException(BaseException):
362 def __init__(self, fancy_arg):
363 BaseException.__init__(self)
364 self.fancy_arg = fancy_arg
365
366 x = DerivedException(fancy_arg=42)
Ezio Melotti2623a372010-11-21 13:34:58 +0000367 self.assertEqual(x.fancy_arg, 42)
Georg Brandlcdcede62006-05-30 08:47:19 +0000368
Armin Rigo53c1692f2006-06-21 21:58:50 +0000369 def testInfiniteRecursion(self):
370 def f():
371 return f()
372 self.assertRaises(RuntimeError, f)
373
374 def g():
375 try:
376 return g()
377 except ValueError:
378 return -1
Antoine Pitrou0668c622008-08-26 22:42:08 +0000379
380 # The test prints an unraisable recursion error when
381 # doing "except ValueError", this is because subclass
382 # checking has recursion checking too.
Martin Panteref85a1a2016-02-28 00:18:43 +0000383 with captured_stderr():
Antoine Pitrou0668c622008-08-26 22:42:08 +0000384 try:
385 g()
386 except RuntimeError:
387 pass
388 except:
389 self.fail("Should have raised KeyError")
390 else:
391 self.fail("Should have raised KeyError")
Armin Rigo53c1692f2006-06-21 21:58:50 +0000392
Brett Cannonca2ca792006-09-09 07:11:46 +0000393 def testUnicodeStrUsage(self):
394 # Make sure both instances and classes have a str and unicode
395 # representation.
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000396 self.assertTrue(str(Exception))
397 self.assertTrue(unicode(Exception))
398 self.assertTrue(str(Exception('a')))
399 self.assertTrue(unicode(Exception(u'a')))
400 self.assertTrue(unicode(Exception(u'\xe1')))
Brett Cannonca2ca792006-09-09 07:11:46 +0000401
Eric Smith2d9856d2010-02-24 14:15:36 +0000402 def testUnicodeChangeAttributes(self):
403 # See issue 7309. This was a crasher.
404
405 u = UnicodeEncodeError('baz', u'xxxxx', 1, 5, 'foo')
406 self.assertEqual(str(u), "'baz' codec can't encode characters in position 1-4: foo")
407 u.end = 2
408 self.assertEqual(str(u), "'baz' codec can't encode character u'\\x78' in position 1: foo")
409 u.end = 5
410 u.reason = 0x345345345345345345
411 self.assertEqual(str(u), "'baz' codec can't encode characters in position 1-4: 965230951443685724997")
412 u.encoding = 4000
413 self.assertEqual(str(u), "'4000' codec can't encode characters in position 1-4: 965230951443685724997")
414 u.start = 1000
415 self.assertEqual(str(u), "'4000' codec can't encode characters in position 1000-4: 965230951443685724997")
416
417 u = UnicodeDecodeError('baz', 'xxxxx', 1, 5, 'foo')
418 self.assertEqual(str(u), "'baz' codec can't decode bytes in position 1-4: foo")
419 u.end = 2
420 self.assertEqual(str(u), "'baz' codec can't decode byte 0x78 in position 1: foo")
421 u.end = 5
422 u.reason = 0x345345345345345345
423 self.assertEqual(str(u), "'baz' codec can't decode bytes in position 1-4: 965230951443685724997")
424 u.encoding = 4000
425 self.assertEqual(str(u), "'4000' codec can't decode bytes in position 1-4: 965230951443685724997")
426 u.start = 1000
427 self.assertEqual(str(u), "'4000' codec can't decode bytes in position 1000-4: 965230951443685724997")
428
429 u = UnicodeTranslateError(u'xxxx', 1, 5, 'foo')
430 self.assertEqual(str(u), "can't translate characters in position 1-4: foo")
431 u.end = 2
432 self.assertEqual(str(u), "can't translate character u'\\x78' in position 1: foo")
433 u.end = 5
434 u.reason = 0x345345345345345345
435 self.assertEqual(str(u), "can't translate characters in position 1-4: 965230951443685724997")
436 u.start = 1000
437 self.assertEqual(str(u), "can't translate characters in position 1000-4: 965230951443685724997")
438
Benjamin Petersonc4e6e0a2014-04-02 12:15:06 -0400439 def test_unicode_errors_no_object(self):
440 # See issue #21134.
Benjamin Peterson07681002014-04-02 15:51:38 -0400441 klasses = UnicodeEncodeError, UnicodeDecodeError, UnicodeTranslateError
Benjamin Petersonc4e6e0a2014-04-02 12:15:06 -0400442 for klass in klasses:
443 self.assertEqual(str(klass.__new__(klass)), "")
444
Amaury Forgeot d'Arc246daed2008-07-31 00:42:16 +0000445 def test_badisinstance(self):
446 # Bug #2542: if issubclass(e, MyException) raises an exception,
447 # it should be ignored
448 class Meta(type):
449 def __subclasscheck__(cls, subclass):
450 raise ValueError()
451
452 class MyException(Exception):
453 __metaclass__ = Meta
454 pass
455
Martin Panteref85a1a2016-02-28 00:18:43 +0000456 with captured_stderr() as stderr:
Amaury Forgeot d'Arc246daed2008-07-31 00:42:16 +0000457 try:
458 raise KeyError()
459 except MyException, e:
460 self.fail("exception should not be a MyException")
461 except KeyError:
462 pass
463 except:
Antoine Pitrou0668c622008-08-26 22:42:08 +0000464 self.fail("Should have raised KeyError")
Amaury Forgeot d'Arc246daed2008-07-31 00:42:16 +0000465 else:
Antoine Pitrou0668c622008-08-26 22:42:08 +0000466 self.fail("Should have raised KeyError")
467
Martin Panteref85a1a2016-02-28 00:18:43 +0000468 with captured_stderr() as stderr:
Antoine Pitrou0668c622008-08-26 22:42:08 +0000469 def g():
470 try:
471 return g()
472 except RuntimeError:
473 return sys.exc_info()
474 e, v, tb = g()
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000475 self.assertTrue(e is RuntimeError, e)
Ezio Melottiaa980582010-01-23 23:04:36 +0000476 self.assertIn("maximum recursion depth exceeded", str(v))
Antoine Pitrou0668c622008-08-26 22:42:08 +0000477
Benjamin Petersonc3349cd2011-07-15 14:15:40 -0500478 def test_new_returns_invalid_instance(self):
479 # See issue #11627.
480 class MyException(Exception):
481 def __new__(cls, *args):
482 return object()
483
484 with self.assertRaises(TypeError):
485 raise MyException
Brett Cannonca2ca792006-09-09 07:11:46 +0000486
Benjamin Peterson78fc7052011-10-27 08:20:01 -0400487 def test_assert_with_tuple_arg(self):
488 try:
489 assert False, (3,)
490 except AssertionError as e:
491 self.assertEqual(str(e), "(3,)")
492
Mark Dickinson7cac1c22013-03-03 11:13:34 +0000493 def test_bad_exception_clearing(self):
494 # See issue 16445: use of Py_XDECREF instead of Py_CLEAR in
495 # BaseException_set_message gave a possible way to segfault the
496 # interpreter.
497 class Nasty(str):
498 def __del__(message):
499 del e.message
500
501 e = ValueError(Nasty("msg"))
502 e.args = ()
503 del e.message
504
Ezio Melottif84caf42009-12-24 22:25:17 +0000505
506# Helper class used by TestSameStrAndUnicodeMsg
507class ExcWithOverriddenStr(Exception):
508 """Subclass of Exception that accepts a keyword 'msg' arg that is
509 returned by __str__. 'msg' won't be included in self.args"""
510 def __init__(self, *args, **kwargs):
511 self.msg = kwargs.pop('msg') # msg should always be present
512 super(ExcWithOverriddenStr, self).__init__(*args, **kwargs)
513 def __str__(self):
514 return self.msg
515
516
517class TestSameStrAndUnicodeMsg(unittest.TestCase):
518 """unicode(err) should return the same message of str(err). See #6108"""
519
520 def check_same_msg(self, exc, msg):
521 """Helper function that checks if str(exc) == unicode(exc) == msg"""
522 self.assertEqual(str(exc), msg)
523 self.assertEqual(str(exc), unicode(exc))
524
525 def test_builtin_exceptions(self):
526 """Check same msg for built-in exceptions"""
527 # These exceptions implement a __str__ method that uses the args
528 # to create a better error message. unicode(e) should return the same
529 # message.
530 exceptions = [
531 SyntaxError('invalid syntax', ('<string>', 1, 3, '2+*3')),
532 IOError(2, 'No such file or directory'),
533 KeyError('both should have the same quotes'),
534 UnicodeDecodeError('ascii', '\xc3\xa0', 0, 1,
535 'ordinal not in range(128)'),
536 UnicodeEncodeError('ascii', u'\u1234', 0, 1,
537 'ordinal not in range(128)')
538 ]
539 for exception in exceptions:
540 self.assertEqual(str(exception), unicode(exception))
541
542 def test_0_args(self):
543 """Check same msg for Exception with 0 args"""
544 # str() and unicode() on an Exception with no args should return an
545 # empty string
546 self.check_same_msg(Exception(), '')
547
548 def test_0_args_with_overridden___str__(self):
549 """Check same msg for exceptions with 0 args and overridden __str__"""
550 # str() and unicode() on an exception with overridden __str__ that
551 # returns an ascii-only string should return the same string
552 for msg in ('foo', u'foo'):
553 self.check_same_msg(ExcWithOverriddenStr(msg=msg), msg)
554
555 # if __str__ returns a non-ascii unicode string str() should fail
556 # but unicode() should return the unicode string
557 e = ExcWithOverriddenStr(msg=u'f\xf6\xf6') # no args
558 self.assertRaises(UnicodeEncodeError, str, e)
559 self.assertEqual(unicode(e), u'f\xf6\xf6')
560
561 def test_1_arg(self):
562 """Check same msg for Exceptions with 1 arg"""
563 for arg in ('foo', u'foo'):
564 self.check_same_msg(Exception(arg), arg)
565
566 # if __str__ is not overridden and self.args[0] is a non-ascii unicode
567 # string, str() should try to return str(self.args[0]) and fail.
568 # unicode() should return unicode(self.args[0]) and succeed.
569 e = Exception(u'f\xf6\xf6')
570 self.assertRaises(UnicodeEncodeError, str, e)
571 self.assertEqual(unicode(e), u'f\xf6\xf6')
572
573 def test_1_arg_with_overridden___str__(self):
574 """Check same msg for exceptions with overridden __str__ and 1 arg"""
575 # when __str__ is overridden and __unicode__ is not implemented
576 # unicode(e) returns the same as unicode(e.__str__()).
577 for msg in ('foo', u'foo'):
578 self.check_same_msg(ExcWithOverriddenStr('arg', msg=msg), msg)
579
580 # if __str__ returns a non-ascii unicode string, str() should fail
581 # but unicode() should succeed.
582 e = ExcWithOverriddenStr('arg', msg=u'f\xf6\xf6') # 1 arg
583 self.assertRaises(UnicodeEncodeError, str, e)
584 self.assertEqual(unicode(e), u'f\xf6\xf6')
585
586 def test_many_args(self):
587 """Check same msg for Exceptions with many args"""
588 argslist = [
589 (3, 'foo'),
590 (1, u'foo', 'bar'),
591 (4, u'f\xf6\xf6', u'bar', 'baz')
592 ]
593 # both str() and unicode() should return a repr() of the args
594 for args in argslist:
595 self.check_same_msg(Exception(*args), repr(args))
596
597 def test_many_args_with_overridden___str__(self):
598 """Check same msg for exceptions with overridden __str__ and many args"""
599 # if __str__ returns an ascii string / ascii unicode string
600 # both str() and unicode() should succeed
601 for msg in ('foo', u'foo'):
602 e = ExcWithOverriddenStr('arg1', u'arg2', u'f\xf6\xf6', msg=msg)
603 self.check_same_msg(e, msg)
604
605 # if __str__ returns a non-ascii unicode string, str() should fail
606 # but unicode() should succeed
607 e = ExcWithOverriddenStr('arg1', u'f\xf6\xf6', u'arg3', # 3 args
608 msg=u'f\xf6\xf6')
609 self.assertRaises(UnicodeEncodeError, str, e)
610 self.assertEqual(unicode(e), u'f\xf6\xf6')
611
Benjamin Peterson8eeb1dc2010-06-28 15:36:40 +0000612 @cpython_only
Georg Brandl740cdc32009-12-28 08:34:58 +0000613 def test_exception_with_doc(self):
614 import _testcapi
615 doc2 = "This is a test docstring."
616 doc4 = "This is another test docstring."
617
618 self.assertRaises(SystemError, _testcapi.make_exception_with_doc,
619 "error1")
620
621 # test basic usage of PyErr_NewException
622 error1 = _testcapi.make_exception_with_doc("_testcapi.error1")
623 self.assertIs(type(error1), type)
624 self.assertTrue(issubclass(error1, Exception))
625 self.assertIsNone(error1.__doc__)
626
627 # test with given docstring
628 error2 = _testcapi.make_exception_with_doc("_testcapi.error2", doc2)
629 self.assertEqual(error2.__doc__, doc2)
630
631 # test with explicit base (without docstring)
632 error3 = _testcapi.make_exception_with_doc("_testcapi.error3",
633 base=error2)
634 self.assertTrue(issubclass(error3, error2))
635
636 # test with explicit base tuple
637 class C(object):
638 pass
639 error4 = _testcapi.make_exception_with_doc("_testcapi.error4", doc4,
640 (error3, C))
641 self.assertTrue(issubclass(error4, error3))
642 self.assertTrue(issubclass(error4, C))
643 self.assertEqual(error4.__doc__, doc4)
644
645 # test with explicit dictionary
646 error5 = _testcapi.make_exception_with_doc("_testcapi.error5", "",
647 error4, {'a': 1})
648 self.assertTrue(issubclass(error5, error4))
649 self.assertEqual(error5.a, 1)
650 self.assertEqual(error5.__doc__, "")
651
Martin Panteref85a1a2016-02-28 00:18:43 +0000652 def test_unraisable(self):
653 # Issue #22836: PyErr_WriteUnraisable() should give sensible reports
654 class BrokenDel:
655 def __del__(self):
656 exc = ValueError("del is broken")
657 # In Python 3, the following line would be in the report:
658 raise exc
659
660 class BrokenRepr(BrokenDel):
661 def __repr__(self):
662 raise AttributeError("repr() is broken")
663
664 class BrokenExceptionDel:
665 def __del__(self):
666 exc = BrokenStrException()
667 # In Python 3, the following line would be in the report:
668 raise exc
669
670 for test_class in (BrokenDel, BrokenRepr, BrokenExceptionDel):
671 obj = test_class()
672 with captured_stderr() as stderr:
673 del obj
674 report = stderr.getvalue()
675 self.assertRegexpMatches(report, "Exception.* ignored")
676 if test_class is BrokenRepr:
677 self.assertIn("<object repr() failed>", report)
678 else:
679 self.assertIn("__del__", report)
680 if test_class is BrokenExceptionDel:
681 self.assertIn("BrokenStrException", report)
682 self.assertIn("<exception repr() failed>", report)
683 else:
684 self.assertIn("ValueError", report)
685 self.assertIn("del is broken", report)
686 self.assertTrue(report.endswith("\n"))
687
688 def test_unhandled(self):
689 # Check for sensible reporting of unhandled exceptions
690 for exc_type in (ValueError, BrokenStrException):
691 try:
692 exc = exc_type("test message")
693 # The following line is included in the traceback report:
694 raise exc
695 except exc_type:
696 with captured_stderr() as stderr:
697 sys.__excepthook__(*sys.exc_info())
698 report = stderr.getvalue()
699 self.assertIn("test_exceptions.py", report)
700 self.assertIn("raise exc", report)
701 self.assertIn(exc_type.__name__, report)
702 if exc_type is BrokenStrException:
703 self.assertIn("<exception str() failed>", report)
704 else:
705 self.assertIn("test message", report)
706 self.assertTrue(report.endswith("\n"))
707
Ezio Melottif84caf42009-12-24 22:25:17 +0000708
Georg Brandlcdcede62006-05-30 08:47:19 +0000709def test_main():
Ezio Melottif84caf42009-12-24 22:25:17 +0000710 run_unittest(ExceptionTests, TestSameStrAndUnicodeMsg)
Georg Brandlcdcede62006-05-30 08:47:19 +0000711
712if __name__ == '__main__':
713 test_main()