blob: b9500318792cb7bba8f552bb859bd9218bc7f6dd [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
Florent Xicluna6257a7b2010-03-31 22:01:03 +00008from test.test_support import (TESTFN, unlink, run_unittest, captured_output,
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
Guido van Rossum3bead091992-01-27 17:00:37 +000012# XXX This is not really enough, each *operation* should be tested!
13
Georg Brandlcdcede62006-05-30 08:47:19 +000014class ExceptionTests(unittest.TestCase):
Barry Warsawb9c1d3d2001-08-13 23:07:00 +000015
Georg Brandlcdcede62006-05-30 08:47:19 +000016 def testReload(self):
17 # Reloading the built-in exceptions module failed prior to Py2.2, while it
18 # should act the same as reloading built-in sys.
19 try:
Ezio Melotti1f517e12010-02-02 17:34:37 +000020 from imp import reload
Georg Brandlcdcede62006-05-30 08:47:19 +000021 import exceptions
22 reload(exceptions)
23 except ImportError, e:
24 self.fail("reloading exceptions: %s" % e)
Jeremy Hylton56c807d2000-06-20 18:52:57 +000025
Georg Brandlcdcede62006-05-30 08:47:19 +000026 def raise_catch(self, exc, excname):
27 try:
28 raise exc, "spam"
29 except exc, err:
30 buf1 = str(err)
31 try:
32 raise exc("spam")
33 except exc, err:
34 buf2 = str(err)
Ezio Melotti2623a372010-11-21 13:34:58 +000035 self.assertEqual(buf1, buf2)
36 self.assertEqual(exc.__name__, excname)
Guido van Rossum3bead091992-01-27 17:00:37 +000037
Georg Brandlcdcede62006-05-30 08:47:19 +000038 def testRaising(self):
Tim Petersdd55b0a2006-05-30 23:28:02 +000039 self.raise_catch(AttributeError, "AttributeError")
Georg Brandlcdcede62006-05-30 08:47:19 +000040 self.assertRaises(AttributeError, getattr, sys, "undefined_attribute")
Guido van Rossum3bead091992-01-27 17:00:37 +000041
Georg Brandlcdcede62006-05-30 08:47:19 +000042 self.raise_catch(EOFError, "EOFError")
43 fp = open(TESTFN, 'w')
44 fp.close()
45 fp = open(TESTFN, 'r')
46 savestdin = sys.stdin
47 try:
48 try:
49 sys.stdin = fp
50 x = raw_input()
51 except EOFError:
52 pass
53 finally:
54 sys.stdin = savestdin
55 fp.close()
56 unlink(TESTFN)
Guido van Rossum3bead091992-01-27 17:00:37 +000057
Georg Brandlcdcede62006-05-30 08:47:19 +000058 self.raise_catch(IOError, "IOError")
59 self.assertRaises(IOError, open, 'this file does not exist', 'r')
Guido van Rossum3bead091992-01-27 17:00:37 +000060
Georg Brandlcdcede62006-05-30 08:47:19 +000061 self.raise_catch(ImportError, "ImportError")
62 self.assertRaises(ImportError, __import__, "undefined_module")
Guido van Rossum3bead091992-01-27 17:00:37 +000063
Georg Brandlcdcede62006-05-30 08:47:19 +000064 self.raise_catch(IndexError, "IndexError")
65 x = []
66 self.assertRaises(IndexError, x.__getitem__, 10)
Guido van Rossum3bead091992-01-27 17:00:37 +000067
Georg Brandlcdcede62006-05-30 08:47:19 +000068 self.raise_catch(KeyError, "KeyError")
69 x = {}
70 self.assertRaises(KeyError, x.__getitem__, 'key')
Guido van Rossum3bead091992-01-27 17:00:37 +000071
Georg Brandlcdcede62006-05-30 08:47:19 +000072 self.raise_catch(KeyboardInterrupt, "KeyboardInterrupt")
Guido van Rossum3bead091992-01-27 17:00:37 +000073
Georg Brandlcdcede62006-05-30 08:47:19 +000074 self.raise_catch(MemoryError, "MemoryError")
Guido van Rossum3bead091992-01-27 17:00:37 +000075
Georg Brandlcdcede62006-05-30 08:47:19 +000076 self.raise_catch(NameError, "NameError")
77 try: x = undefined_variable
78 except NameError: pass
Guido van Rossum3bead091992-01-27 17:00:37 +000079
Georg Brandlcdcede62006-05-30 08:47:19 +000080 self.raise_catch(OverflowError, "OverflowError")
81 x = 1
82 for dummy in range(128):
83 x += x # this simply shouldn't blow up
Guido van Rossum3bead091992-01-27 17:00:37 +000084
Georg Brandlcdcede62006-05-30 08:47:19 +000085 self.raise_catch(RuntimeError, "RuntimeError")
Guido van Rossum3bead091992-01-27 17:00:37 +000086
Georg Brandlcdcede62006-05-30 08:47:19 +000087 self.raise_catch(SyntaxError, "SyntaxError")
88 try: exec '/\n'
89 except SyntaxError: pass
Guido van Rossum3bead091992-01-27 17:00:37 +000090
Georg Brandlcdcede62006-05-30 08:47:19 +000091 self.raise_catch(IndentationError, "IndentationError")
Fred Drake72e48bd2000-09-08 16:32:34 +000092
Georg Brandlcdcede62006-05-30 08:47:19 +000093 self.raise_catch(TabError, "TabError")
94 # can only be tested under -tt, and is the only test for -tt
Serhiy Storchaka5312a7f2015-01-31 11:27:06 +020095 #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 +000096 #except TabError: pass
97 #else: self.fail("TabError not raised")
Fred Drake72e48bd2000-09-08 16:32:34 +000098
Georg Brandlcdcede62006-05-30 08:47:19 +000099 self.raise_catch(SystemError, "SystemError")
Fred Drake72e48bd2000-09-08 16:32:34 +0000100
Georg Brandlcdcede62006-05-30 08:47:19 +0000101 self.raise_catch(SystemExit, "SystemExit")
102 self.assertRaises(SystemExit, sys.exit, 0)
Fred Drake85f36392000-07-11 17:53:00 +0000103
Georg Brandlcdcede62006-05-30 08:47:19 +0000104 self.raise_catch(TypeError, "TypeError")
105 try: [] + ()
106 except TypeError: pass
Fred Drake85f36392000-07-11 17:53:00 +0000107
Georg Brandlcdcede62006-05-30 08:47:19 +0000108 self.raise_catch(ValueError, "ValueError")
109 self.assertRaises(ValueError, chr, 10000)
Guido van Rossum3bead091992-01-27 17:00:37 +0000110
Georg Brandlcdcede62006-05-30 08:47:19 +0000111 self.raise_catch(ZeroDivisionError, "ZeroDivisionError")
Ezio Melotti1f517e12010-02-02 17:34:37 +0000112 try: x = 1 // 0
Georg Brandlcdcede62006-05-30 08:47:19 +0000113 except ZeroDivisionError: pass
Guido van Rossum3bead091992-01-27 17:00:37 +0000114
Georg Brandlcdcede62006-05-30 08:47:19 +0000115 self.raise_catch(Exception, "Exception")
Ezio Melotti1f517e12010-02-02 17:34:37 +0000116 try: x = 1 // 0
Georg Brandlcdcede62006-05-30 08:47:19 +0000117 except Exception, e: pass
Guido van Rossum3bead091992-01-27 17:00:37 +0000118
Georg Brandlcdcede62006-05-30 08:47:19 +0000119 def testSyntaxErrorMessage(self):
Neal Norwitze152aab2006-06-02 04:45:53 +0000120 # make sure the right exception message is raised for each of
121 # these code fragments
Guido van Rossum3bead091992-01-27 17:00:37 +0000122
Georg Brandlcdcede62006-05-30 08:47:19 +0000123 def ckmsg(src, msg):
124 try:
125 compile(src, '<fragment>', 'exec')
126 except SyntaxError, e:
127 if e.msg != msg:
128 self.fail("expected %s, got %s" % (msg, e.msg))
129 else:
130 self.fail("failed to get expected SyntaxError")
Guido van Rossum3bead091992-01-27 17:00:37 +0000131
Georg Brandlcdcede62006-05-30 08:47:19 +0000132 s = '''while 1:
133 try:
134 pass
135 finally:
136 continue'''
Barry Warsaw992cb8a2000-05-25 23:16:54 +0000137
Georg Brandlcdcede62006-05-30 08:47:19 +0000138 if not sys.platform.startswith('java'):
139 ckmsg(s, "'continue' not supported inside 'finally' clause")
Jeremy Hyltonede049b2001-09-26 20:01:13 +0000140
Georg Brandlcdcede62006-05-30 08:47:19 +0000141 s = '''if 1:
142 try:
143 continue
144 except:
145 pass'''
Jeremy Hyltonede049b2001-09-26 20:01:13 +0000146
Georg Brandlcdcede62006-05-30 08:47:19 +0000147 ckmsg(s, "'continue' not properly in loop")
148 ckmsg("continue\n", "'continue' not properly in loop")
Jeremy Hyltonede049b2001-09-26 20:01:13 +0000149
Benjamin Peterson8eeb1dc2010-06-28 15:36:40 +0000150 @cpython_only
Georg Brandlcdcede62006-05-30 08:47:19 +0000151 def testSettingException(self):
Neal Norwitze152aab2006-06-02 04:45:53 +0000152 # test that setting an exception at the C level works even if the
153 # exception object can't be constructed.
Finn Bockaa3dc452001-12-08 10:15:48 +0000154
Georg Brandlcdcede62006-05-30 08:47:19 +0000155 class BadException:
156 def __init__(self_):
157 raise RuntimeError, "can't instantiate BadException"
Jeremy Hyltonede049b2001-09-26 20:01:13 +0000158
Georg Brandlcdcede62006-05-30 08:47:19 +0000159 def test_capi1():
160 import _testcapi
161 try:
162 _testcapi.raise_exception(BadException, 1)
163 except TypeError, err:
164 exc, err, tb = sys.exc_info()
165 co = tb.tb_frame.f_code
Ezio Melotti2623a372010-11-21 13:34:58 +0000166 self.assertEqual(co.co_name, "test_capi1")
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000167 self.assertTrue(co.co_filename.endswith('test_exceptions'+os.extsep+'py'))
Georg Brandlcdcede62006-05-30 08:47:19 +0000168 else:
169 self.fail("Expected exception")
Richard Jones7b9558d2006-05-27 12:29:24 +0000170
Georg Brandlcdcede62006-05-30 08:47:19 +0000171 def test_capi2():
172 import _testcapi
173 try:
174 _testcapi.raise_exception(BadException, 0)
175 except RuntimeError, err:
176 exc, err, tb = sys.exc_info()
177 co = tb.tb_frame.f_code
Ezio Melotti2623a372010-11-21 13:34:58 +0000178 self.assertEqual(co.co_name, "__init__")
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000179 self.assertTrue(co.co_filename.endswith('test_exceptions'+os.extsep+'py'))
Georg Brandlcdcede62006-05-30 08:47:19 +0000180 co2 = tb.tb_frame.f_back.f_code
Ezio Melotti2623a372010-11-21 13:34:58 +0000181 self.assertEqual(co2.co_name, "test_capi2")
Georg Brandlcdcede62006-05-30 08:47:19 +0000182 else:
183 self.fail("Expected exception")
Richard Jones7b9558d2006-05-27 12:29:24 +0000184
Georg Brandlcdcede62006-05-30 08:47:19 +0000185 if not sys.platform.startswith('java'):
186 test_capi1()
187 test_capi2()
Georg Brandl05f97bf2006-05-30 07:13:29 +0000188
Thomas Hellerdf08f0b2006-10-27 18:31:36 +0000189 def test_WindowsError(self):
190 try:
191 WindowsError
192 except NameError:
193 pass
194 else:
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000195 self.assertEqual(str(WindowsError(1001)),
Thomas Hellerdf08f0b2006-10-27 18:31:36 +0000196 "1001")
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000197 self.assertEqual(str(WindowsError(1001, "message")),
Thomas Hellerdf08f0b2006-10-27 18:31:36 +0000198 "[Error 1001] message")
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000199 self.assertEqual(WindowsError(1001, "message").errno, 22)
200 self.assertEqual(WindowsError(1001, "message").winerror, 1001)
Thomas Hellerdf08f0b2006-10-27 18:31:36 +0000201
Ezio Melotti1f517e12010-02-02 17:34:37 +0000202 @ignore_deprecation_warnings
Georg Brandlcdcede62006-05-30 08:47:19 +0000203 def testAttributes(self):
Neal Norwitze152aab2006-06-02 04:45:53 +0000204 # test that exception attributes are happy
Tim Petersdd55b0a2006-05-30 23:28:02 +0000205
Georg Brandlcdcede62006-05-30 08:47:19 +0000206 exceptionList = [
Georg Brandle08940e2006-06-01 13:00:49 +0000207 (BaseException, (), {'message' : '', 'args' : ()}),
208 (BaseException, (1, ), {'message' : 1, 'args' : (1,)}),
209 (BaseException, ('foo',),
210 {'message' : 'foo', 'args' : ('foo',)}),
211 (BaseException, ('foo', 1),
212 {'message' : '', 'args' : ('foo', 1)}),
213 (SystemExit, ('foo',),
214 {'message' : 'foo', 'args' : ('foo',), 'code' : 'foo'}),
215 (IOError, ('foo',),
Georg Brandl3267d282006-09-30 09:03:42 +0000216 {'message' : 'foo', 'args' : ('foo',), 'filename' : None,
217 'errno' : None, 'strerror' : None}),
Georg Brandle08940e2006-06-01 13:00:49 +0000218 (IOError, ('foo', 'bar'),
Georg Brandl3267d282006-09-30 09:03:42 +0000219 {'message' : '', 'args' : ('foo', 'bar'), 'filename' : None,
220 'errno' : 'foo', 'strerror' : 'bar'}),
Georg Brandle08940e2006-06-01 13:00:49 +0000221 (IOError, ('foo', 'bar', 'baz'),
Georg Brandl3267d282006-09-30 09:03:42 +0000222 {'message' : '', 'args' : ('foo', 'bar'), 'filename' : 'baz',
223 'errno' : 'foo', 'strerror' : 'bar'}),
224 (IOError, ('foo', 'bar', 'baz', 'quux'),
225 {'message' : '', 'args' : ('foo', 'bar', 'baz', 'quux')}),
Georg Brandle08940e2006-06-01 13:00:49 +0000226 (EnvironmentError, ('errnoStr', 'strErrorStr', 'filenameStr'),
227 {'message' : '', 'args' : ('errnoStr', 'strErrorStr'),
228 'strerror' : 'strErrorStr', 'errno' : 'errnoStr',
229 'filename' : 'filenameStr'}),
230 (EnvironmentError, (1, 'strErrorStr', 'filenameStr'),
231 {'message' : '', 'args' : (1, 'strErrorStr'), 'errno' : 1,
232 'strerror' : 'strErrorStr', 'filename' : 'filenameStr'}),
Brett Cannonf8267df2007-02-28 18:15:00 +0000233 (SyntaxError, (), {'message' : '', 'msg' : None, 'text' : None,
234 'filename' : None, 'lineno' : None, 'offset' : None,
235 'print_file_and_line' : None}),
Georg Brandle08940e2006-06-01 13:00:49 +0000236 (SyntaxError, ('msgStr',),
237 {'message' : 'msgStr', 'args' : ('msgStr',), 'text' : None,
238 'print_file_and_line' : None, 'msg' : 'msgStr',
239 'filename' : None, 'lineno' : None, 'offset' : None}),
240 (SyntaxError, ('msgStr', ('filenameStr', 'linenoStr', 'offsetStr',
241 'textStr')),
242 {'message' : '', 'offset' : 'offsetStr', 'text' : 'textStr',
243 'args' : ('msgStr', ('filenameStr', 'linenoStr',
244 'offsetStr', 'textStr')),
245 'print_file_and_line' : None, 'msg' : 'msgStr',
246 'filename' : 'filenameStr', 'lineno' : 'linenoStr'}),
247 (SyntaxError, ('msgStr', 'filenameStr', 'linenoStr', 'offsetStr',
248 'textStr', 'print_file_and_lineStr'),
249 {'message' : '', 'text' : None,
250 'args' : ('msgStr', 'filenameStr', 'linenoStr', 'offsetStr',
251 'textStr', 'print_file_and_lineStr'),
252 'print_file_and_line' : None, 'msg' : 'msgStr',
253 'filename' : None, 'lineno' : None, 'offset' : None}),
254 (UnicodeError, (), {'message' : '', 'args' : (),}),
Georg Brandl38f62372006-09-06 06:50:05 +0000255 (UnicodeEncodeError, ('ascii', u'a', 0, 1, 'ordinal not in range'),
256 {'message' : '', 'args' : ('ascii', u'a', 0, 1,
257 'ordinal not in range'),
258 'encoding' : 'ascii', 'object' : u'a',
259 'start' : 0, 'reason' : 'ordinal not in range'}),
260 (UnicodeDecodeError, ('ascii', '\xff', 0, 1, 'ordinal not in range'),
Georg Brandle08940e2006-06-01 13:00:49 +0000261 {'message' : '', 'args' : ('ascii', '\xff', 0, 1,
Georg Brandl38f62372006-09-06 06:50:05 +0000262 'ordinal not in range'),
Georg Brandle08940e2006-06-01 13:00:49 +0000263 'encoding' : 'ascii', 'object' : '\xff',
Georg Brandl38f62372006-09-06 06:50:05 +0000264 'start' : 0, 'reason' : 'ordinal not in range'}),
Georg Brandle08940e2006-06-01 13:00:49 +0000265 (UnicodeTranslateError, (u"\u3042", 0, 1, "ouch"),
266 {'message' : '', 'args' : (u'\u3042', 0, 1, 'ouch'),
267 'object' : u'\u3042', 'reason' : 'ouch',
268 'start' : 0, 'end' : 1}),
269 ]
Georg Brandlcdcede62006-05-30 08:47:19 +0000270 try:
271 exceptionList.append(
Georg Brandle08940e2006-06-01 13:00:49 +0000272 (WindowsError, (1, 'strErrorStr', 'filenameStr'),
273 {'message' : '', 'args' : (1, 'strErrorStr'),
274 'strerror' : 'strErrorStr', 'winerror' : 1,
275 'errno' : 22, 'filename' : 'filenameStr'})
276 )
Tim Peters80dc76e2006-06-07 06:57:51 +0000277 except NameError:
278 pass
Georg Brandlcdcede62006-05-30 08:47:19 +0000279
Ezio Melotti1f517e12010-02-02 17:34:37 +0000280 for exc, args, expected in exceptionList:
281 try:
282 raise exc(*args)
283 except BaseException, e:
284 if type(e) is not exc:
285 raise
286 # Verify module name
Ezio Melotti2623a372010-11-21 13:34:58 +0000287 self.assertEqual(type(e).__module__, 'exceptions')
Ezio Melotti1f517e12010-02-02 17:34:37 +0000288 # Verify no ref leaks in Exc_str()
289 s = str(e)
290 for checkArgName in expected:
Ezio Melotti2623a372010-11-21 13:34:58 +0000291 self.assertEqual(repr(getattr(e, checkArgName)),
292 repr(expected[checkArgName]),
293 'exception "%s", attribute "%s"' %
294 (repr(e), checkArgName))
Tim Petersdd55b0a2006-05-30 23:28:02 +0000295
Ezio Melotti1f517e12010-02-02 17:34:37 +0000296 # test for pickling support
297 for p in pickle, cPickle:
298 for protocol in range(p.HIGHEST_PROTOCOL + 1):
299 new = p.loads(p.dumps(e, protocol))
300 for checkArgName in expected:
301 got = repr(getattr(new, checkArgName))
302 want = repr(expected[checkArgName])
Ezio Melotti2623a372010-11-21 13:34:58 +0000303 self.assertEqual(got, want,
304 'pickled "%r", attribute "%s"' %
305 (e, checkArgName))
Georg Brandlcdcede62006-05-30 08:47:19 +0000306
Georg Brandl0674d3f2009-09-16 20:30:09 +0000307
308 def testDeprecatedMessageAttribute(self):
309 # Accessing BaseException.message and relying on its value set by
310 # BaseException.__init__ triggers a deprecation warning.
311 exc = BaseException("foo")
Florent Xicluna6257a7b2010-03-31 22:01:03 +0000312 with check_warnings(("BaseException.message has been deprecated "
313 "as of Python 2.6", DeprecationWarning)) as w:
314 self.assertEqual(exc.message, "foo")
315 self.assertEqual(len(w.warnings), 1)
Georg Brandl0674d3f2009-09-16 20:30:09 +0000316
317 def testRegularMessageAttribute(self):
318 # Accessing BaseException.message after explicitly setting a value
319 # for it does not trigger a deprecation warning.
320 exc = BaseException("foo")
321 exc.message = "bar"
Florent Xicluna6257a7b2010-03-31 22:01:03 +0000322 with check_warnings(quiet=True) as w:
323 self.assertEqual(exc.message, "bar")
324 self.assertEqual(len(w.warnings), 0)
Georg Brandl0674d3f2009-09-16 20:30:09 +0000325 # Deleting the message is supported, too.
326 del exc.message
327 with self.assertRaises(AttributeError):
328 exc.message
329
Ezio Melotti1f517e12010-02-02 17:34:37 +0000330 @ignore_deprecation_warnings
Georg Brandl0674d3f2009-09-16 20:30:09 +0000331 def testPickleMessageAttribute(self):
332 # Pickling with message attribute must work, as well.
333 e = Exception("foo")
334 f = Exception("foo")
335 f.message = "bar"
336 for p in pickle, cPickle:
337 ep = p.loads(p.dumps(e))
Ezio Melotti1f517e12010-02-02 17:34:37 +0000338 self.assertEqual(ep.message, "foo")
Georg Brandl0674d3f2009-09-16 20:30:09 +0000339 fp = p.loads(p.dumps(f))
340 self.assertEqual(fp.message, "bar")
341
Ezio Melotti1f517e12010-02-02 17:34:37 +0000342 @ignore_deprecation_warnings
Brett Cannone05e6b02007-01-29 04:41:44 +0000343 def testSlicing(self):
344 # Test that you can slice an exception directly instead of requiring
345 # going through the 'args' attribute.
346 args = (1, 2, 3)
347 exc = BaseException(*args)
Senthil Kumarance8e33a2010-01-08 19:04:16 +0000348 self.assertEqual(exc[:], args)
Ezio Melotti1f517e12010-02-02 17:34:37 +0000349 self.assertEqual(exc.args[:], args)
Brett Cannone05e6b02007-01-29 04:41:44 +0000350
Georg Brandlcdcede62006-05-30 08:47:19 +0000351 def testKeywordArgs(self):
Neal Norwitze152aab2006-06-02 04:45:53 +0000352 # test that builtin exception don't take keyword args,
353 # but user-defined subclasses can if they want
Georg Brandlcdcede62006-05-30 08:47:19 +0000354 self.assertRaises(TypeError, BaseException, a=1)
Georg Brandle08940e2006-06-01 13:00:49 +0000355
Georg Brandlcdcede62006-05-30 08:47:19 +0000356 class DerivedException(BaseException):
357 def __init__(self, fancy_arg):
358 BaseException.__init__(self)
359 self.fancy_arg = fancy_arg
360
361 x = DerivedException(fancy_arg=42)
Ezio Melotti2623a372010-11-21 13:34:58 +0000362 self.assertEqual(x.fancy_arg, 42)
Georg Brandlcdcede62006-05-30 08:47:19 +0000363
Armin Rigo53c1692f2006-06-21 21:58:50 +0000364 def testInfiniteRecursion(self):
365 def f():
366 return f()
367 self.assertRaises(RuntimeError, f)
368
369 def g():
370 try:
371 return g()
372 except ValueError:
373 return -1
Antoine Pitrou0668c622008-08-26 22:42:08 +0000374
375 # The test prints an unraisable recursion error when
376 # doing "except ValueError", this is because subclass
377 # checking has recursion checking too.
378 with captured_output("stderr"):
379 try:
380 g()
381 except RuntimeError:
382 pass
383 except:
384 self.fail("Should have raised KeyError")
385 else:
386 self.fail("Should have raised KeyError")
Armin Rigo53c1692f2006-06-21 21:58:50 +0000387
Brett Cannonca2ca792006-09-09 07:11:46 +0000388 def testUnicodeStrUsage(self):
389 # Make sure both instances and classes have a str and unicode
390 # representation.
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000391 self.assertTrue(str(Exception))
392 self.assertTrue(unicode(Exception))
393 self.assertTrue(str(Exception('a')))
394 self.assertTrue(unicode(Exception(u'a')))
395 self.assertTrue(unicode(Exception(u'\xe1')))
Brett Cannonca2ca792006-09-09 07:11:46 +0000396
Eric Smith2d9856d2010-02-24 14:15:36 +0000397 def testUnicodeChangeAttributes(self):
398 # See issue 7309. This was a crasher.
399
400 u = UnicodeEncodeError('baz', u'xxxxx', 1, 5, 'foo')
401 self.assertEqual(str(u), "'baz' codec can't encode characters in position 1-4: foo")
402 u.end = 2
403 self.assertEqual(str(u), "'baz' codec can't encode character u'\\x78' in position 1: foo")
404 u.end = 5
405 u.reason = 0x345345345345345345
406 self.assertEqual(str(u), "'baz' codec can't encode characters in position 1-4: 965230951443685724997")
407 u.encoding = 4000
408 self.assertEqual(str(u), "'4000' codec can't encode characters in position 1-4: 965230951443685724997")
409 u.start = 1000
410 self.assertEqual(str(u), "'4000' codec can't encode characters in position 1000-4: 965230951443685724997")
411
412 u = UnicodeDecodeError('baz', 'xxxxx', 1, 5, 'foo')
413 self.assertEqual(str(u), "'baz' codec can't decode bytes in position 1-4: foo")
414 u.end = 2
415 self.assertEqual(str(u), "'baz' codec can't decode byte 0x78 in position 1: foo")
416 u.end = 5
417 u.reason = 0x345345345345345345
418 self.assertEqual(str(u), "'baz' codec can't decode bytes in position 1-4: 965230951443685724997")
419 u.encoding = 4000
420 self.assertEqual(str(u), "'4000' codec can't decode bytes in position 1-4: 965230951443685724997")
421 u.start = 1000
422 self.assertEqual(str(u), "'4000' codec can't decode bytes in position 1000-4: 965230951443685724997")
423
424 u = UnicodeTranslateError(u'xxxx', 1, 5, 'foo')
425 self.assertEqual(str(u), "can't translate characters in position 1-4: foo")
426 u.end = 2
427 self.assertEqual(str(u), "can't translate character u'\\x78' in position 1: foo")
428 u.end = 5
429 u.reason = 0x345345345345345345
430 self.assertEqual(str(u), "can't translate characters in position 1-4: 965230951443685724997")
431 u.start = 1000
432 self.assertEqual(str(u), "can't translate characters in position 1000-4: 965230951443685724997")
433
Benjamin Petersonc4e6e0a2014-04-02 12:15:06 -0400434 def test_unicode_errors_no_object(self):
435 # See issue #21134.
Benjamin Peterson07681002014-04-02 15:51:38 -0400436 klasses = UnicodeEncodeError, UnicodeDecodeError, UnicodeTranslateError
Benjamin Petersonc4e6e0a2014-04-02 12:15:06 -0400437 for klass in klasses:
438 self.assertEqual(str(klass.__new__(klass)), "")
439
Amaury Forgeot d'Arc246daed2008-07-31 00:42:16 +0000440 def test_badisinstance(self):
441 # Bug #2542: if issubclass(e, MyException) raises an exception,
442 # it should be ignored
443 class Meta(type):
444 def __subclasscheck__(cls, subclass):
445 raise ValueError()
446
447 class MyException(Exception):
448 __metaclass__ = Meta
449 pass
450
451 with captured_output("stderr") as stderr:
452 try:
453 raise KeyError()
454 except MyException, e:
455 self.fail("exception should not be a MyException")
456 except KeyError:
457 pass
458 except:
Antoine Pitrou0668c622008-08-26 22:42:08 +0000459 self.fail("Should have raised KeyError")
Amaury Forgeot d'Arc246daed2008-07-31 00:42:16 +0000460 else:
Antoine Pitrou0668c622008-08-26 22:42:08 +0000461 self.fail("Should have raised KeyError")
462
463 with captured_output("stderr") as stderr:
464 def g():
465 try:
466 return g()
467 except RuntimeError:
468 return sys.exc_info()
469 e, v, tb = g()
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000470 self.assertTrue(e is RuntimeError, e)
Ezio Melottiaa980582010-01-23 23:04:36 +0000471 self.assertIn("maximum recursion depth exceeded", str(v))
Antoine Pitrou0668c622008-08-26 22:42:08 +0000472
Benjamin Petersonc3349cd2011-07-15 14:15:40 -0500473 def test_new_returns_invalid_instance(self):
474 # See issue #11627.
475 class MyException(Exception):
476 def __new__(cls, *args):
477 return object()
478
479 with self.assertRaises(TypeError):
480 raise MyException
Brett Cannonca2ca792006-09-09 07:11:46 +0000481
Benjamin Peterson78fc7052011-10-27 08:20:01 -0400482 def test_assert_with_tuple_arg(self):
483 try:
484 assert False, (3,)
485 except AssertionError as e:
486 self.assertEqual(str(e), "(3,)")
487
Mark Dickinson7cac1c22013-03-03 11:13:34 +0000488 def test_bad_exception_clearing(self):
489 # See issue 16445: use of Py_XDECREF instead of Py_CLEAR in
490 # BaseException_set_message gave a possible way to segfault the
491 # interpreter.
492 class Nasty(str):
493 def __del__(message):
494 del e.message
495
496 e = ValueError(Nasty("msg"))
497 e.args = ()
498 del e.message
499
Ezio Melottif84caf42009-12-24 22:25:17 +0000500
501# Helper class used by TestSameStrAndUnicodeMsg
502class ExcWithOverriddenStr(Exception):
503 """Subclass of Exception that accepts a keyword 'msg' arg that is
504 returned by __str__. 'msg' won't be included in self.args"""
505 def __init__(self, *args, **kwargs):
506 self.msg = kwargs.pop('msg') # msg should always be present
507 super(ExcWithOverriddenStr, self).__init__(*args, **kwargs)
508 def __str__(self):
509 return self.msg
510
511
512class TestSameStrAndUnicodeMsg(unittest.TestCase):
513 """unicode(err) should return the same message of str(err). See #6108"""
514
515 def check_same_msg(self, exc, msg):
516 """Helper function that checks if str(exc) == unicode(exc) == msg"""
517 self.assertEqual(str(exc), msg)
518 self.assertEqual(str(exc), unicode(exc))
519
520 def test_builtin_exceptions(self):
521 """Check same msg for built-in exceptions"""
522 # These exceptions implement a __str__ method that uses the args
523 # to create a better error message. unicode(e) should return the same
524 # message.
525 exceptions = [
526 SyntaxError('invalid syntax', ('<string>', 1, 3, '2+*3')),
527 IOError(2, 'No such file or directory'),
528 KeyError('both should have the same quotes'),
529 UnicodeDecodeError('ascii', '\xc3\xa0', 0, 1,
530 'ordinal not in range(128)'),
531 UnicodeEncodeError('ascii', u'\u1234', 0, 1,
532 'ordinal not in range(128)')
533 ]
534 for exception in exceptions:
535 self.assertEqual(str(exception), unicode(exception))
536
537 def test_0_args(self):
538 """Check same msg for Exception with 0 args"""
539 # str() and unicode() on an Exception with no args should return an
540 # empty string
541 self.check_same_msg(Exception(), '')
542
543 def test_0_args_with_overridden___str__(self):
544 """Check same msg for exceptions with 0 args and overridden __str__"""
545 # str() and unicode() on an exception with overridden __str__ that
546 # returns an ascii-only string should return the same string
547 for msg in ('foo', u'foo'):
548 self.check_same_msg(ExcWithOverriddenStr(msg=msg), msg)
549
550 # if __str__ returns a non-ascii unicode string str() should fail
551 # but unicode() should return the unicode string
552 e = ExcWithOverriddenStr(msg=u'f\xf6\xf6') # no args
553 self.assertRaises(UnicodeEncodeError, str, e)
554 self.assertEqual(unicode(e), u'f\xf6\xf6')
555
556 def test_1_arg(self):
557 """Check same msg for Exceptions with 1 arg"""
558 for arg in ('foo', u'foo'):
559 self.check_same_msg(Exception(arg), arg)
560
561 # if __str__ is not overridden and self.args[0] is a non-ascii unicode
562 # string, str() should try to return str(self.args[0]) and fail.
563 # unicode() should return unicode(self.args[0]) and succeed.
564 e = Exception(u'f\xf6\xf6')
565 self.assertRaises(UnicodeEncodeError, str, e)
566 self.assertEqual(unicode(e), u'f\xf6\xf6')
567
568 def test_1_arg_with_overridden___str__(self):
569 """Check same msg for exceptions with overridden __str__ and 1 arg"""
570 # when __str__ is overridden and __unicode__ is not implemented
571 # unicode(e) returns the same as unicode(e.__str__()).
572 for msg in ('foo', u'foo'):
573 self.check_same_msg(ExcWithOverriddenStr('arg', msg=msg), msg)
574
575 # if __str__ returns a non-ascii unicode string, str() should fail
576 # but unicode() should succeed.
577 e = ExcWithOverriddenStr('arg', msg=u'f\xf6\xf6') # 1 arg
578 self.assertRaises(UnicodeEncodeError, str, e)
579 self.assertEqual(unicode(e), u'f\xf6\xf6')
580
581 def test_many_args(self):
582 """Check same msg for Exceptions with many args"""
583 argslist = [
584 (3, 'foo'),
585 (1, u'foo', 'bar'),
586 (4, u'f\xf6\xf6', u'bar', 'baz')
587 ]
588 # both str() and unicode() should return a repr() of the args
589 for args in argslist:
590 self.check_same_msg(Exception(*args), repr(args))
591
592 def test_many_args_with_overridden___str__(self):
593 """Check same msg for exceptions with overridden __str__ and many args"""
594 # if __str__ returns an ascii string / ascii unicode string
595 # both str() and unicode() should succeed
596 for msg in ('foo', u'foo'):
597 e = ExcWithOverriddenStr('arg1', u'arg2', u'f\xf6\xf6', msg=msg)
598 self.check_same_msg(e, msg)
599
600 # if __str__ returns a non-ascii unicode string, str() should fail
601 # but unicode() should succeed
602 e = ExcWithOverriddenStr('arg1', u'f\xf6\xf6', u'arg3', # 3 args
603 msg=u'f\xf6\xf6')
604 self.assertRaises(UnicodeEncodeError, str, e)
605 self.assertEqual(unicode(e), u'f\xf6\xf6')
606
Benjamin Peterson8eeb1dc2010-06-28 15:36:40 +0000607 @cpython_only
Georg Brandl740cdc32009-12-28 08:34:58 +0000608 def test_exception_with_doc(self):
609 import _testcapi
610 doc2 = "This is a test docstring."
611 doc4 = "This is another test docstring."
612
613 self.assertRaises(SystemError, _testcapi.make_exception_with_doc,
614 "error1")
615
616 # test basic usage of PyErr_NewException
617 error1 = _testcapi.make_exception_with_doc("_testcapi.error1")
618 self.assertIs(type(error1), type)
619 self.assertTrue(issubclass(error1, Exception))
620 self.assertIsNone(error1.__doc__)
621
622 # test with given docstring
623 error2 = _testcapi.make_exception_with_doc("_testcapi.error2", doc2)
624 self.assertEqual(error2.__doc__, doc2)
625
626 # test with explicit base (without docstring)
627 error3 = _testcapi.make_exception_with_doc("_testcapi.error3",
628 base=error2)
629 self.assertTrue(issubclass(error3, error2))
630
631 # test with explicit base tuple
632 class C(object):
633 pass
634 error4 = _testcapi.make_exception_with_doc("_testcapi.error4", doc4,
635 (error3, C))
636 self.assertTrue(issubclass(error4, error3))
637 self.assertTrue(issubclass(error4, C))
638 self.assertEqual(error4.__doc__, doc4)
639
640 # test with explicit dictionary
641 error5 = _testcapi.make_exception_with_doc("_testcapi.error5", "",
642 error4, {'a': 1})
643 self.assertTrue(issubclass(error5, error4))
644 self.assertEqual(error5.a, 1)
645 self.assertEqual(error5.__doc__, "")
646
Ezio Melottif84caf42009-12-24 22:25:17 +0000647
Georg Brandlcdcede62006-05-30 08:47:19 +0000648def test_main():
Ezio Melottif84caf42009-12-24 22:25:17 +0000649 run_unittest(ExceptionTests, TestSameStrAndUnicodeMsg)
Georg Brandlcdcede62006-05-30 08:47:19 +0000650
651if __name__ == '__main__':
652 test_main()