blob: 89e5758419fc8adc082a49bbe212b808d2b9ac10 [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,
9 check_warnings)
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)
35 self.assertEquals(buf1, buf2)
36 self.assertEquals(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
95 #try: compile("try:\n\t1/0\n \t1/0\nfinally:\n pass\n", '<string>', 'exec')
96 #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
Georg Brandlcdcede62006-05-30 08:47:19 +0000150 def testSettingException(self):
Neal Norwitze152aab2006-06-02 04:45:53 +0000151 # test that setting an exception at the C level works even if the
152 # exception object can't be constructed.
Finn Bockaa3dc452001-12-08 10:15:48 +0000153
Georg Brandlcdcede62006-05-30 08:47:19 +0000154 class BadException:
155 def __init__(self_):
156 raise RuntimeError, "can't instantiate BadException"
Jeremy Hyltonede049b2001-09-26 20:01:13 +0000157
Georg Brandlcdcede62006-05-30 08:47:19 +0000158 def test_capi1():
159 import _testcapi
160 try:
161 _testcapi.raise_exception(BadException, 1)
162 except TypeError, err:
163 exc, err, tb = sys.exc_info()
164 co = tb.tb_frame.f_code
165 self.assertEquals(co.co_name, "test_capi1")
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000166 self.assertTrue(co.co_filename.endswith('test_exceptions'+os.extsep+'py'))
Georg Brandlcdcede62006-05-30 08:47:19 +0000167 else:
168 self.fail("Expected exception")
Richard Jones7b9558d2006-05-27 12:29:24 +0000169
Georg Brandlcdcede62006-05-30 08:47:19 +0000170 def test_capi2():
171 import _testcapi
172 try:
173 _testcapi.raise_exception(BadException, 0)
174 except RuntimeError, err:
175 exc, err, tb = sys.exc_info()
176 co = tb.tb_frame.f_code
177 self.assertEquals(co.co_name, "__init__")
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000178 self.assertTrue(co.co_filename.endswith('test_exceptions'+os.extsep+'py'))
Georg Brandlcdcede62006-05-30 08:47:19 +0000179 co2 = tb.tb_frame.f_back.f_code
180 self.assertEquals(co2.co_name, "test_capi2")
181 else:
182 self.fail("Expected exception")
Richard Jones7b9558d2006-05-27 12:29:24 +0000183
Georg Brandlcdcede62006-05-30 08:47:19 +0000184 if not sys.platform.startswith('java'):
185 test_capi1()
186 test_capi2()
Georg Brandl05f97bf2006-05-30 07:13:29 +0000187
Thomas Hellerdf08f0b2006-10-27 18:31:36 +0000188 def test_WindowsError(self):
189 try:
190 WindowsError
191 except NameError:
192 pass
193 else:
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000194 self.assertEqual(str(WindowsError(1001)),
Thomas Hellerdf08f0b2006-10-27 18:31:36 +0000195 "1001")
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000196 self.assertEqual(str(WindowsError(1001, "message")),
Thomas Hellerdf08f0b2006-10-27 18:31:36 +0000197 "[Error 1001] message")
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000198 self.assertEqual(WindowsError(1001, "message").errno, 22)
199 self.assertEqual(WindowsError(1001, "message").winerror, 1001)
Thomas Hellerdf08f0b2006-10-27 18:31:36 +0000200
Ezio Melotti1f517e12010-02-02 17:34:37 +0000201 @ignore_deprecation_warnings
Georg Brandlcdcede62006-05-30 08:47:19 +0000202 def testAttributes(self):
Neal Norwitze152aab2006-06-02 04:45:53 +0000203 # test that exception attributes are happy
Tim Petersdd55b0a2006-05-30 23:28:02 +0000204
Georg Brandlcdcede62006-05-30 08:47:19 +0000205 exceptionList = [
Georg Brandle08940e2006-06-01 13:00:49 +0000206 (BaseException, (), {'message' : '', 'args' : ()}),
207 (BaseException, (1, ), {'message' : 1, 'args' : (1,)}),
208 (BaseException, ('foo',),
209 {'message' : 'foo', 'args' : ('foo',)}),
210 (BaseException, ('foo', 1),
211 {'message' : '', 'args' : ('foo', 1)}),
212 (SystemExit, ('foo',),
213 {'message' : 'foo', 'args' : ('foo',), 'code' : 'foo'}),
214 (IOError, ('foo',),
Georg Brandl3267d282006-09-30 09:03:42 +0000215 {'message' : 'foo', 'args' : ('foo',), 'filename' : None,
216 'errno' : None, 'strerror' : None}),
Georg Brandle08940e2006-06-01 13:00:49 +0000217 (IOError, ('foo', 'bar'),
Georg Brandl3267d282006-09-30 09:03:42 +0000218 {'message' : '', 'args' : ('foo', 'bar'), 'filename' : None,
219 'errno' : 'foo', 'strerror' : 'bar'}),
Georg Brandle08940e2006-06-01 13:00:49 +0000220 (IOError, ('foo', 'bar', 'baz'),
Georg Brandl3267d282006-09-30 09:03:42 +0000221 {'message' : '', 'args' : ('foo', 'bar'), 'filename' : 'baz',
222 'errno' : 'foo', 'strerror' : 'bar'}),
223 (IOError, ('foo', 'bar', 'baz', 'quux'),
224 {'message' : '', 'args' : ('foo', 'bar', 'baz', 'quux')}),
Georg Brandle08940e2006-06-01 13:00:49 +0000225 (EnvironmentError, ('errnoStr', 'strErrorStr', 'filenameStr'),
226 {'message' : '', 'args' : ('errnoStr', 'strErrorStr'),
227 'strerror' : 'strErrorStr', 'errno' : 'errnoStr',
228 'filename' : 'filenameStr'}),
229 (EnvironmentError, (1, 'strErrorStr', 'filenameStr'),
230 {'message' : '', 'args' : (1, 'strErrorStr'), 'errno' : 1,
231 'strerror' : 'strErrorStr', 'filename' : 'filenameStr'}),
Brett Cannonf8267df2007-02-28 18:15:00 +0000232 (SyntaxError, (), {'message' : '', 'msg' : None, 'text' : None,
233 'filename' : None, 'lineno' : None, 'offset' : None,
234 'print_file_and_line' : None}),
Georg Brandle08940e2006-06-01 13:00:49 +0000235 (SyntaxError, ('msgStr',),
236 {'message' : 'msgStr', 'args' : ('msgStr',), 'text' : None,
237 'print_file_and_line' : None, 'msg' : 'msgStr',
238 'filename' : None, 'lineno' : None, 'offset' : None}),
239 (SyntaxError, ('msgStr', ('filenameStr', 'linenoStr', 'offsetStr',
240 'textStr')),
241 {'message' : '', 'offset' : 'offsetStr', 'text' : 'textStr',
242 'args' : ('msgStr', ('filenameStr', 'linenoStr',
243 'offsetStr', 'textStr')),
244 'print_file_and_line' : None, 'msg' : 'msgStr',
245 'filename' : 'filenameStr', 'lineno' : 'linenoStr'}),
246 (SyntaxError, ('msgStr', 'filenameStr', 'linenoStr', 'offsetStr',
247 'textStr', 'print_file_and_lineStr'),
248 {'message' : '', 'text' : None,
249 'args' : ('msgStr', 'filenameStr', 'linenoStr', 'offsetStr',
250 'textStr', 'print_file_and_lineStr'),
251 'print_file_and_line' : None, 'msg' : 'msgStr',
252 'filename' : None, 'lineno' : None, 'offset' : None}),
253 (UnicodeError, (), {'message' : '', 'args' : (),}),
Georg Brandl38f62372006-09-06 06:50:05 +0000254 (UnicodeEncodeError, ('ascii', u'a', 0, 1, 'ordinal not in range'),
255 {'message' : '', 'args' : ('ascii', u'a', 0, 1,
256 'ordinal not in range'),
257 'encoding' : 'ascii', 'object' : u'a',
258 'start' : 0, 'reason' : 'ordinal not in range'}),
259 (UnicodeDecodeError, ('ascii', '\xff', 0, 1, 'ordinal not in range'),
Georg Brandle08940e2006-06-01 13:00:49 +0000260 {'message' : '', 'args' : ('ascii', '\xff', 0, 1,
Georg Brandl38f62372006-09-06 06:50:05 +0000261 'ordinal not in range'),
Georg Brandle08940e2006-06-01 13:00:49 +0000262 'encoding' : 'ascii', 'object' : '\xff',
Georg Brandl38f62372006-09-06 06:50:05 +0000263 'start' : 0, 'reason' : 'ordinal not in range'}),
Georg Brandle08940e2006-06-01 13:00:49 +0000264 (UnicodeTranslateError, (u"\u3042", 0, 1, "ouch"),
265 {'message' : '', 'args' : (u'\u3042', 0, 1, 'ouch'),
266 'object' : u'\u3042', 'reason' : 'ouch',
267 'start' : 0, 'end' : 1}),
268 ]
Georg Brandlcdcede62006-05-30 08:47:19 +0000269 try:
270 exceptionList.append(
Georg Brandle08940e2006-06-01 13:00:49 +0000271 (WindowsError, (1, 'strErrorStr', 'filenameStr'),
272 {'message' : '', 'args' : (1, 'strErrorStr'),
273 'strerror' : 'strErrorStr', 'winerror' : 1,
274 'errno' : 22, 'filename' : 'filenameStr'})
275 )
Tim Peters80dc76e2006-06-07 06:57:51 +0000276 except NameError:
277 pass
Georg Brandlcdcede62006-05-30 08:47:19 +0000278
Ezio Melotti1f517e12010-02-02 17:34:37 +0000279 for exc, args, expected in exceptionList:
280 try:
281 raise exc(*args)
282 except BaseException, e:
283 if type(e) is not exc:
284 raise
285 # Verify module name
286 self.assertEquals(type(e).__module__, 'exceptions')
287 # Verify no ref leaks in Exc_str()
288 s = str(e)
289 for checkArgName in expected:
290 self.assertEquals(repr(getattr(e, checkArgName)),
291 repr(expected[checkArgName]),
292 'exception "%s", attribute "%s"' %
293 (repr(e), checkArgName))
Tim Petersdd55b0a2006-05-30 23:28:02 +0000294
Ezio Melotti1f517e12010-02-02 17:34:37 +0000295 # test for pickling support
296 for p in pickle, cPickle:
297 for protocol in range(p.HIGHEST_PROTOCOL + 1):
298 new = p.loads(p.dumps(e, protocol))
299 for checkArgName in expected:
300 got = repr(getattr(new, checkArgName))
301 want = repr(expected[checkArgName])
302 self.assertEquals(got, want,
303 'pickled "%r", attribute "%s"' %
304 (e, checkArgName))
Georg Brandlcdcede62006-05-30 08:47:19 +0000305
Georg Brandl0674d3f2009-09-16 20:30:09 +0000306
307 def testDeprecatedMessageAttribute(self):
308 # Accessing BaseException.message and relying on its value set by
309 # BaseException.__init__ triggers a deprecation warning.
310 exc = BaseException("foo")
Florent Xicluna6257a7b2010-03-31 22:01:03 +0000311 with check_warnings(("BaseException.message has been deprecated "
312 "as of Python 2.6", DeprecationWarning)) as w:
313 self.assertEqual(exc.message, "foo")
314 self.assertEqual(len(w.warnings), 1)
Georg Brandl0674d3f2009-09-16 20:30:09 +0000315
316 def testRegularMessageAttribute(self):
317 # Accessing BaseException.message after explicitly setting a value
318 # for it does not trigger a deprecation warning.
319 exc = BaseException("foo")
320 exc.message = "bar"
Florent Xicluna6257a7b2010-03-31 22:01:03 +0000321 with check_warnings(quiet=True) as w:
322 self.assertEqual(exc.message, "bar")
323 self.assertEqual(len(w.warnings), 0)
Georg Brandl0674d3f2009-09-16 20:30:09 +0000324 # Deleting the message is supported, too.
325 del exc.message
326 with self.assertRaises(AttributeError):
327 exc.message
328
Ezio Melotti1f517e12010-02-02 17:34:37 +0000329 @ignore_deprecation_warnings
Georg Brandl0674d3f2009-09-16 20:30:09 +0000330 def testPickleMessageAttribute(self):
331 # Pickling with message attribute must work, as well.
332 e = Exception("foo")
333 f = Exception("foo")
334 f.message = "bar"
335 for p in pickle, cPickle:
336 ep = p.loads(p.dumps(e))
Ezio Melotti1f517e12010-02-02 17:34:37 +0000337 self.assertEqual(ep.message, "foo")
Georg Brandl0674d3f2009-09-16 20:30:09 +0000338 fp = p.loads(p.dumps(f))
339 self.assertEqual(fp.message, "bar")
340
Ezio Melotti1f517e12010-02-02 17:34:37 +0000341 @ignore_deprecation_warnings
Brett Cannone05e6b02007-01-29 04:41:44 +0000342 def testSlicing(self):
343 # Test that you can slice an exception directly instead of requiring
344 # going through the 'args' attribute.
345 args = (1, 2, 3)
346 exc = BaseException(*args)
Senthil Kumarance8e33a2010-01-08 19:04:16 +0000347 self.assertEqual(exc[:], args)
Ezio Melotti1f517e12010-02-02 17:34:37 +0000348 self.assertEqual(exc.args[:], args)
Brett Cannone05e6b02007-01-29 04:41:44 +0000349
Georg Brandlcdcede62006-05-30 08:47:19 +0000350 def testKeywordArgs(self):
Neal Norwitze152aab2006-06-02 04:45:53 +0000351 # test that builtin exception don't take keyword args,
352 # but user-defined subclasses can if they want
Georg Brandlcdcede62006-05-30 08:47:19 +0000353 self.assertRaises(TypeError, BaseException, a=1)
Georg Brandle08940e2006-06-01 13:00:49 +0000354
Georg Brandlcdcede62006-05-30 08:47:19 +0000355 class DerivedException(BaseException):
356 def __init__(self, fancy_arg):
357 BaseException.__init__(self)
358 self.fancy_arg = fancy_arg
359
360 x = DerivedException(fancy_arg=42)
361 self.assertEquals(x.fancy_arg, 42)
362
Armin Rigo53c1692f2006-06-21 21:58:50 +0000363 def testInfiniteRecursion(self):
364 def f():
365 return f()
366 self.assertRaises(RuntimeError, f)
367
368 def g():
369 try:
370 return g()
371 except ValueError:
372 return -1
Antoine Pitrou0668c622008-08-26 22:42:08 +0000373
374 # The test prints an unraisable recursion error when
375 # doing "except ValueError", this is because subclass
376 # checking has recursion checking too.
377 with captured_output("stderr"):
378 try:
379 g()
380 except RuntimeError:
381 pass
382 except:
383 self.fail("Should have raised KeyError")
384 else:
385 self.fail("Should have raised KeyError")
Armin Rigo53c1692f2006-06-21 21:58:50 +0000386
Brett Cannonca2ca792006-09-09 07:11:46 +0000387 def testUnicodeStrUsage(self):
388 # Make sure both instances and classes have a str and unicode
389 # representation.
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000390 self.assertTrue(str(Exception))
391 self.assertTrue(unicode(Exception))
392 self.assertTrue(str(Exception('a')))
393 self.assertTrue(unicode(Exception(u'a')))
394 self.assertTrue(unicode(Exception(u'\xe1')))
Brett Cannonca2ca792006-09-09 07:11:46 +0000395
Eric Smith2d9856d2010-02-24 14:15:36 +0000396 def testUnicodeChangeAttributes(self):
397 # See issue 7309. This was a crasher.
398
399 u = UnicodeEncodeError('baz', u'xxxxx', 1, 5, 'foo')
400 self.assertEqual(str(u), "'baz' codec can't encode characters in position 1-4: foo")
401 u.end = 2
402 self.assertEqual(str(u), "'baz' codec can't encode character u'\\x78' in position 1: foo")
403 u.end = 5
404 u.reason = 0x345345345345345345
405 self.assertEqual(str(u), "'baz' codec can't encode characters in position 1-4: 965230951443685724997")
406 u.encoding = 4000
407 self.assertEqual(str(u), "'4000' codec can't encode characters in position 1-4: 965230951443685724997")
408 u.start = 1000
409 self.assertEqual(str(u), "'4000' codec can't encode characters in position 1000-4: 965230951443685724997")
410
411 u = UnicodeDecodeError('baz', 'xxxxx', 1, 5, 'foo')
412 self.assertEqual(str(u), "'baz' codec can't decode bytes in position 1-4: foo")
413 u.end = 2
414 self.assertEqual(str(u), "'baz' codec can't decode byte 0x78 in position 1: foo")
415 u.end = 5
416 u.reason = 0x345345345345345345
417 self.assertEqual(str(u), "'baz' codec can't decode bytes in position 1-4: 965230951443685724997")
418 u.encoding = 4000
419 self.assertEqual(str(u), "'4000' codec can't decode bytes in position 1-4: 965230951443685724997")
420 u.start = 1000
421 self.assertEqual(str(u), "'4000' codec can't decode bytes in position 1000-4: 965230951443685724997")
422
423 u = UnicodeTranslateError(u'xxxx', 1, 5, 'foo')
424 self.assertEqual(str(u), "can't translate characters in position 1-4: foo")
425 u.end = 2
426 self.assertEqual(str(u), "can't translate character u'\\x78' in position 1: foo")
427 u.end = 5
428 u.reason = 0x345345345345345345
429 self.assertEqual(str(u), "can't translate characters in position 1-4: 965230951443685724997")
430 u.start = 1000
431 self.assertEqual(str(u), "can't translate characters in position 1000-4: 965230951443685724997")
432
Amaury Forgeot d'Arc246daed2008-07-31 00:42:16 +0000433 def test_badisinstance(self):
434 # Bug #2542: if issubclass(e, MyException) raises an exception,
435 # it should be ignored
436 class Meta(type):
437 def __subclasscheck__(cls, subclass):
438 raise ValueError()
439
440 class MyException(Exception):
441 __metaclass__ = Meta
442 pass
443
444 with captured_output("stderr") as stderr:
445 try:
446 raise KeyError()
447 except MyException, e:
448 self.fail("exception should not be a MyException")
449 except KeyError:
450 pass
451 except:
Antoine Pitrou0668c622008-08-26 22:42:08 +0000452 self.fail("Should have raised KeyError")
Amaury Forgeot d'Arc246daed2008-07-31 00:42:16 +0000453 else:
Antoine Pitrou0668c622008-08-26 22:42:08 +0000454 self.fail("Should have raised KeyError")
455
456 with captured_output("stderr") as stderr:
457 def g():
458 try:
459 return g()
460 except RuntimeError:
461 return sys.exc_info()
462 e, v, tb = g()
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000463 self.assertTrue(e is RuntimeError, e)
Ezio Melottiaa980582010-01-23 23:04:36 +0000464 self.assertIn("maximum recursion depth exceeded", str(v))
Antoine Pitrou0668c622008-08-26 22:42:08 +0000465
Brett Cannonca2ca792006-09-09 07:11:46 +0000466
Ezio Melottif84caf42009-12-24 22:25:17 +0000467
468# Helper class used by TestSameStrAndUnicodeMsg
469class ExcWithOverriddenStr(Exception):
470 """Subclass of Exception that accepts a keyword 'msg' arg that is
471 returned by __str__. 'msg' won't be included in self.args"""
472 def __init__(self, *args, **kwargs):
473 self.msg = kwargs.pop('msg') # msg should always be present
474 super(ExcWithOverriddenStr, self).__init__(*args, **kwargs)
475 def __str__(self):
476 return self.msg
477
478
479class TestSameStrAndUnicodeMsg(unittest.TestCase):
480 """unicode(err) should return the same message of str(err). See #6108"""
481
482 def check_same_msg(self, exc, msg):
483 """Helper function that checks if str(exc) == unicode(exc) == msg"""
484 self.assertEqual(str(exc), msg)
485 self.assertEqual(str(exc), unicode(exc))
486
487 def test_builtin_exceptions(self):
488 """Check same msg for built-in exceptions"""
489 # These exceptions implement a __str__ method that uses the args
490 # to create a better error message. unicode(e) should return the same
491 # message.
492 exceptions = [
493 SyntaxError('invalid syntax', ('<string>', 1, 3, '2+*3')),
494 IOError(2, 'No such file or directory'),
495 KeyError('both should have the same quotes'),
496 UnicodeDecodeError('ascii', '\xc3\xa0', 0, 1,
497 'ordinal not in range(128)'),
498 UnicodeEncodeError('ascii', u'\u1234', 0, 1,
499 'ordinal not in range(128)')
500 ]
501 for exception in exceptions:
502 self.assertEqual(str(exception), unicode(exception))
503
504 def test_0_args(self):
505 """Check same msg for Exception with 0 args"""
506 # str() and unicode() on an Exception with no args should return an
507 # empty string
508 self.check_same_msg(Exception(), '')
509
510 def test_0_args_with_overridden___str__(self):
511 """Check same msg for exceptions with 0 args and overridden __str__"""
512 # str() and unicode() on an exception with overridden __str__ that
513 # returns an ascii-only string should return the same string
514 for msg in ('foo', u'foo'):
515 self.check_same_msg(ExcWithOverriddenStr(msg=msg), msg)
516
517 # if __str__ returns a non-ascii unicode string str() should fail
518 # but unicode() should return the unicode string
519 e = ExcWithOverriddenStr(msg=u'f\xf6\xf6') # no args
520 self.assertRaises(UnicodeEncodeError, str, e)
521 self.assertEqual(unicode(e), u'f\xf6\xf6')
522
523 def test_1_arg(self):
524 """Check same msg for Exceptions with 1 arg"""
525 for arg in ('foo', u'foo'):
526 self.check_same_msg(Exception(arg), arg)
527
528 # if __str__ is not overridden and self.args[0] is a non-ascii unicode
529 # string, str() should try to return str(self.args[0]) and fail.
530 # unicode() should return unicode(self.args[0]) and succeed.
531 e = Exception(u'f\xf6\xf6')
532 self.assertRaises(UnicodeEncodeError, str, e)
533 self.assertEqual(unicode(e), u'f\xf6\xf6')
534
535 def test_1_arg_with_overridden___str__(self):
536 """Check same msg for exceptions with overridden __str__ and 1 arg"""
537 # when __str__ is overridden and __unicode__ is not implemented
538 # unicode(e) returns the same as unicode(e.__str__()).
539 for msg in ('foo', u'foo'):
540 self.check_same_msg(ExcWithOverriddenStr('arg', msg=msg), msg)
541
542 # if __str__ returns a non-ascii unicode string, str() should fail
543 # but unicode() should succeed.
544 e = ExcWithOverriddenStr('arg', msg=u'f\xf6\xf6') # 1 arg
545 self.assertRaises(UnicodeEncodeError, str, e)
546 self.assertEqual(unicode(e), u'f\xf6\xf6')
547
548 def test_many_args(self):
549 """Check same msg for Exceptions with many args"""
550 argslist = [
551 (3, 'foo'),
552 (1, u'foo', 'bar'),
553 (4, u'f\xf6\xf6', u'bar', 'baz')
554 ]
555 # both str() and unicode() should return a repr() of the args
556 for args in argslist:
557 self.check_same_msg(Exception(*args), repr(args))
558
559 def test_many_args_with_overridden___str__(self):
560 """Check same msg for exceptions with overridden __str__ and many args"""
561 # if __str__ returns an ascii string / ascii unicode string
562 # both str() and unicode() should succeed
563 for msg in ('foo', u'foo'):
564 e = ExcWithOverriddenStr('arg1', u'arg2', u'f\xf6\xf6', msg=msg)
565 self.check_same_msg(e, msg)
566
567 # if __str__ returns a non-ascii unicode string, str() should fail
568 # but unicode() should succeed
569 e = ExcWithOverriddenStr('arg1', u'f\xf6\xf6', u'arg3', # 3 args
570 msg=u'f\xf6\xf6')
571 self.assertRaises(UnicodeEncodeError, str, e)
572 self.assertEqual(unicode(e), u'f\xf6\xf6')
573
Georg Brandl740cdc32009-12-28 08:34:58 +0000574 def test_exception_with_doc(self):
575 import _testcapi
576 doc2 = "This is a test docstring."
577 doc4 = "This is another test docstring."
578
579 self.assertRaises(SystemError, _testcapi.make_exception_with_doc,
580 "error1")
581
582 # test basic usage of PyErr_NewException
583 error1 = _testcapi.make_exception_with_doc("_testcapi.error1")
584 self.assertIs(type(error1), type)
585 self.assertTrue(issubclass(error1, Exception))
586 self.assertIsNone(error1.__doc__)
587
588 # test with given docstring
589 error2 = _testcapi.make_exception_with_doc("_testcapi.error2", doc2)
590 self.assertEqual(error2.__doc__, doc2)
591
592 # test with explicit base (without docstring)
593 error3 = _testcapi.make_exception_with_doc("_testcapi.error3",
594 base=error2)
595 self.assertTrue(issubclass(error3, error2))
596
597 # test with explicit base tuple
598 class C(object):
599 pass
600 error4 = _testcapi.make_exception_with_doc("_testcapi.error4", doc4,
601 (error3, C))
602 self.assertTrue(issubclass(error4, error3))
603 self.assertTrue(issubclass(error4, C))
604 self.assertEqual(error4.__doc__, doc4)
605
606 # test with explicit dictionary
607 error5 = _testcapi.make_exception_with_doc("_testcapi.error5", "",
608 error4, {'a': 1})
609 self.assertTrue(issubclass(error5, error4))
610 self.assertEqual(error5.a, 1)
611 self.assertEqual(error5.__doc__, "")
612
Ezio Melottif84caf42009-12-24 22:25:17 +0000613
Georg Brandlcdcede62006-05-30 08:47:19 +0000614def test_main():
Ezio Melottif84caf42009-12-24 22:25:17 +0000615 run_unittest(ExceptionTests, TestSameStrAndUnicodeMsg)
Georg Brandlcdcede62006-05-30 08:47:19 +0000616
617if __name__ == '__main__':
618 test_main()