blob: dcdd885debddcd457bb863d930bb420fb4ba93ad [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
Ezio Melotti1d55ec32010-08-02 23:34:49 +00008from test.test_support import (TESTFN, unlink, run_unittest, captured_output,
9 check_warnings)
Ezio Melotti38a58002010-08-02 03:14:27 +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 Melotti38a58002010-08-02 03:14:27 +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 Melotti38a58002010-08-02 03:14:27 +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 Melotti38a58002010-08-02 03:14:27 +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")
166 self.assert_(co.co_filename.endswith('test_exceptions'+os.extsep+'py'))
167 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__")
178 self.assert_(co.co_filename.endswith('test_exceptions'+os.extsep+'py'))
179 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:
194 self.failUnlessEqual(str(WindowsError(1001)),
195 "1001")
196 self.failUnlessEqual(str(WindowsError(1001, "message")),
197 "[Error 1001] message")
198 self.failUnlessEqual(WindowsError(1001, "message").errno, 22)
199 self.failUnlessEqual(WindowsError(1001, "message").winerror, 1001)
200
Ezio Melotti38a58002010-08-02 03:14:27 +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 Melotti38a58002010-08-02 03:14:27 +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 Melotti38a58002010-08-02 03:14:27 +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 Brandl89971032009-09-16 20:34:51 +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")
Ezio Melotti1d55ec32010-08-02 23:34:49 +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 Brandl89971032009-09-16 20:34:51 +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"
Ezio Melotti1d55ec32010-08-02 23:34:49 +0000321 with check_warnings(quiet=True) as w:
322 self.assertEqual(exc.message, "bar")
323 self.assertEqual(len(w.warnings), 0)
Georg Brandl89971032009-09-16 20:34:51 +0000324 # Deleting the message is supported, too.
325 del exc.message
326 self.assertRaises(AttributeError, getattr, exc, "message")
327
Ezio Melotti38a58002010-08-02 03:14:27 +0000328 @ignore_deprecation_warnings
Georg Brandl89971032009-09-16 20:34:51 +0000329 def testPickleMessageAttribute(self):
330 # Pickling with message attribute must work, as well.
331 e = Exception("foo")
332 f = Exception("foo")
333 f.message = "bar"
334 for p in pickle, cPickle:
335 ep = p.loads(p.dumps(e))
Ezio Melotti38a58002010-08-02 03:14:27 +0000336 self.assertEqual(ep.message, "foo")
Georg Brandl89971032009-09-16 20:34:51 +0000337 fp = p.loads(p.dumps(f))
338 self.assertEqual(fp.message, "bar")
339
Ezio Melotti38a58002010-08-02 03:14:27 +0000340 @ignore_deprecation_warnings
Brett Cannone05e6b02007-01-29 04:41:44 +0000341 def testSlicing(self):
342 # Test that you can slice an exception directly instead of requiring
343 # going through the 'args' attribute.
344 args = (1, 2, 3)
345 exc = BaseException(*args)
346 self.failUnlessEqual(exc[:], args)
Ezio Melotti38a58002010-08-02 03:14:27 +0000347 self.assertEqual(exc.args[:], args)
Brett Cannone05e6b02007-01-29 04:41:44 +0000348
Georg Brandlcdcede62006-05-30 08:47:19 +0000349 def testKeywordArgs(self):
Neal Norwitze152aab2006-06-02 04:45:53 +0000350 # test that builtin exception don't take keyword args,
351 # but user-defined subclasses can if they want
Georg Brandlcdcede62006-05-30 08:47:19 +0000352 self.assertRaises(TypeError, BaseException, a=1)
Georg Brandle08940e2006-06-01 13:00:49 +0000353
Georg Brandlcdcede62006-05-30 08:47:19 +0000354 class DerivedException(BaseException):
355 def __init__(self, fancy_arg):
356 BaseException.__init__(self)
357 self.fancy_arg = fancy_arg
358
359 x = DerivedException(fancy_arg=42)
360 self.assertEquals(x.fancy_arg, 42)
361
Armin Rigo53c1692f2006-06-21 21:58:50 +0000362 def testInfiniteRecursion(self):
363 def f():
364 return f()
365 self.assertRaises(RuntimeError, f)
366
367 def g():
368 try:
369 return g()
370 except ValueError:
371 return -1
Antoine Pitrou0668c622008-08-26 22:42:08 +0000372
373 # The test prints an unraisable recursion error when
374 # doing "except ValueError", this is because subclass
375 # checking has recursion checking too.
376 with captured_output("stderr"):
377 try:
378 g()
379 except RuntimeError:
380 pass
381 except:
382 self.fail("Should have raised KeyError")
383 else:
384 self.fail("Should have raised KeyError")
Armin Rigo53c1692f2006-06-21 21:58:50 +0000385
Brett Cannonca2ca792006-09-09 07:11:46 +0000386 def testUnicodeStrUsage(self):
387 # Make sure both instances and classes have a str and unicode
388 # representation.
389 self.failUnless(str(Exception))
390 self.failUnless(unicode(Exception))
391 self.failUnless(str(Exception('a')))
392 self.failUnless(unicode(Exception(u'a')))
Nick Coghlan524b7772008-07-08 14:08:04 +0000393 self.failUnless(unicode(Exception(u'\xe1')))
Brett Cannonca2ca792006-09-09 07:11:46 +0000394
Eric Smith66807852010-02-24 14:27:37 +0000395 def testUnicodeChangeAttributes(self):
396 # See issue 7309. This was a crasher.
397
398 u = UnicodeEncodeError('baz', u'xxxxx', 1, 5, 'foo')
399 self.assertEqual(str(u), "'baz' codec can't encode characters in position 1-4: foo")
400 u.end = 2
401 self.assertEqual(str(u), "'baz' codec can't encode character u'\\x78' in position 1: foo")
402 u.end = 5
403 u.reason = 0x345345345345345345
404 self.assertEqual(str(u), "'baz' codec can't encode characters in position 1-4: 965230951443685724997")
405 u.encoding = 4000
406 self.assertEqual(str(u), "'4000' codec can't encode characters in position 1-4: 965230951443685724997")
407 u.start = 1000
408 self.assertEqual(str(u), "'4000' codec can't encode characters in position 1000-4: 965230951443685724997")
409
410 u = UnicodeDecodeError('baz', 'xxxxx', 1, 5, 'foo')
411 self.assertEqual(str(u), "'baz' codec can't decode bytes in position 1-4: foo")
412 u.end = 2
413 self.assertEqual(str(u), "'baz' codec can't decode byte 0x78 in position 1: foo")
414 u.end = 5
415 u.reason = 0x345345345345345345
416 self.assertEqual(str(u), "'baz' codec can't decode bytes in position 1-4: 965230951443685724997")
417 u.encoding = 4000
418 self.assertEqual(str(u), "'4000' codec can't decode bytes in position 1-4: 965230951443685724997")
419 u.start = 1000
420 self.assertEqual(str(u), "'4000' codec can't decode bytes in position 1000-4: 965230951443685724997")
421
422 u = UnicodeTranslateError(u'xxxx', 1, 5, 'foo')
423 self.assertEqual(str(u), "can't translate characters in position 1-4: foo")
424 u.end = 2
425 self.assertEqual(str(u), "can't translate character u'\\x78' in position 1: foo")
426 u.end = 5
427 u.reason = 0x345345345345345345
428 self.assertEqual(str(u), "can't translate characters in position 1-4: 965230951443685724997")
429 u.start = 1000
430 self.assertEqual(str(u), "can't translate characters in position 1000-4: 965230951443685724997")
431
Amaury Forgeot d'Arc246daed2008-07-31 00:42:16 +0000432 def test_badisinstance(self):
433 # Bug #2542: if issubclass(e, MyException) raises an exception,
434 # it should be ignored
435 class Meta(type):
436 def __subclasscheck__(cls, subclass):
437 raise ValueError()
438
439 class MyException(Exception):
440 __metaclass__ = Meta
441 pass
442
443 with captured_output("stderr") as stderr:
444 try:
445 raise KeyError()
446 except MyException, e:
447 self.fail("exception should not be a MyException")
448 except KeyError:
449 pass
450 except:
Antoine Pitrou0668c622008-08-26 22:42:08 +0000451 self.fail("Should have raised KeyError")
Amaury Forgeot d'Arc246daed2008-07-31 00:42:16 +0000452 else:
Antoine Pitrou0668c622008-08-26 22:42:08 +0000453 self.fail("Should have raised KeyError")
454
455 with captured_output("stderr") as stderr:
456 def g():
457 try:
458 return g()
459 except RuntimeError:
460 return sys.exc_info()
461 e, v, tb = g()
462 self.assert_(e is RuntimeError, e)
463 self.assert_("maximum recursion depth exceeded" in str(v), v)
464
Brett Cannonca2ca792006-09-09 07:11:46 +0000465
Ezio Melottie7482382009-12-24 22:32:25 +0000466
467# Helper class used by TestSameStrAndUnicodeMsg
468class ExcWithOverriddenStr(Exception):
469 """Subclass of Exception that accepts a keyword 'msg' arg that is
470 returned by __str__. 'msg' won't be included in self.args"""
471 def __init__(self, *args, **kwargs):
472 self.msg = kwargs.pop('msg') # msg should always be present
473 super(ExcWithOverriddenStr, self).__init__(*args, **kwargs)
474 def __str__(self):
475 return self.msg
476
477
478class TestSameStrAndUnicodeMsg(unittest.TestCase):
479 """unicode(err) should return the same message of str(err). See #6108"""
480
481 def check_same_msg(self, exc, msg):
482 """Helper function that checks if str(exc) == unicode(exc) == msg"""
483 self.assertEqual(str(exc), msg)
484 self.assertEqual(str(exc), unicode(exc))
485
486 def test_builtin_exceptions(self):
487 """Check same msg for built-in exceptions"""
488 # These exceptions implement a __str__ method that uses the args
489 # to create a better error message. unicode(e) should return the same
490 # message.
491 exceptions = [
492 SyntaxError('invalid syntax', ('<string>', 1, 3, '2+*3')),
493 IOError(2, 'No such file or directory'),
494 KeyError('both should have the same quotes'),
495 UnicodeDecodeError('ascii', '\xc3\xa0', 0, 1,
496 'ordinal not in range(128)'),
497 UnicodeEncodeError('ascii', u'\u1234', 0, 1,
498 'ordinal not in range(128)')
499 ]
500 for exception in exceptions:
501 self.assertEqual(str(exception), unicode(exception))
502
503 def test_0_args(self):
504 """Check same msg for Exception with 0 args"""
505 # str() and unicode() on an Exception with no args should return an
506 # empty string
507 self.check_same_msg(Exception(), '')
508
509 def test_0_args_with_overridden___str__(self):
510 """Check same msg for exceptions with 0 args and overridden __str__"""
511 # str() and unicode() on an exception with overridden __str__ that
512 # returns an ascii-only string should return the same string
513 for msg in ('foo', u'foo'):
514 self.check_same_msg(ExcWithOverriddenStr(msg=msg), msg)
515
516 # if __str__ returns a non-ascii unicode string str() should fail
517 # but unicode() should return the unicode string
518 e = ExcWithOverriddenStr(msg=u'f\xf6\xf6') # no args
519 self.assertRaises(UnicodeEncodeError, str, e)
520 self.assertEqual(unicode(e), u'f\xf6\xf6')
521
522 def test_1_arg(self):
523 """Check same msg for Exceptions with 1 arg"""
524 for arg in ('foo', u'foo'):
525 self.check_same_msg(Exception(arg), arg)
526
527 # if __str__ is not overridden and self.args[0] is a non-ascii unicode
528 # string, str() should try to return str(self.args[0]) and fail.
529 # unicode() should return unicode(self.args[0]) and succeed.
530 e = Exception(u'f\xf6\xf6')
531 self.assertRaises(UnicodeEncodeError, str, e)
532 self.assertEqual(unicode(e), u'f\xf6\xf6')
533
534 def test_1_arg_with_overridden___str__(self):
535 """Check same msg for exceptions with overridden __str__ and 1 arg"""
536 # when __str__ is overridden and __unicode__ is not implemented
537 # unicode(e) returns the same as unicode(e.__str__()).
538 for msg in ('foo', u'foo'):
539 self.check_same_msg(ExcWithOverriddenStr('arg', msg=msg), msg)
540
541 # if __str__ returns a non-ascii unicode string, str() should fail
542 # but unicode() should succeed.
543 e = ExcWithOverriddenStr('arg', msg=u'f\xf6\xf6') # 1 arg
544 self.assertRaises(UnicodeEncodeError, str, e)
545 self.assertEqual(unicode(e), u'f\xf6\xf6')
546
547 def test_many_args(self):
548 """Check same msg for Exceptions with many args"""
549 argslist = [
550 (3, 'foo'),
551 (1, u'foo', 'bar'),
552 (4, u'f\xf6\xf6', u'bar', 'baz')
553 ]
554 # both str() and unicode() should return a repr() of the args
555 for args in argslist:
556 self.check_same_msg(Exception(*args), repr(args))
557
558 def test_many_args_with_overridden___str__(self):
559 """Check same msg for exceptions with overridden __str__ and many args"""
560 # if __str__ returns an ascii string / ascii unicode string
561 # both str() and unicode() should succeed
562 for msg in ('foo', u'foo'):
563 e = ExcWithOverriddenStr('arg1', u'arg2', u'f\xf6\xf6', msg=msg)
564 self.check_same_msg(e, msg)
565
566 # if __str__ returns a non-ascii unicode string, str() should fail
567 # but unicode() should succeed
568 e = ExcWithOverriddenStr('arg1', u'f\xf6\xf6', u'arg3', # 3 args
569 msg=u'f\xf6\xf6')
570 self.assertRaises(UnicodeEncodeError, str, e)
571 self.assertEqual(unicode(e), u'f\xf6\xf6')
572
573
Georg Brandlcdcede62006-05-30 08:47:19 +0000574def test_main():
Ezio Melottie7482382009-12-24 22:32:25 +0000575 run_unittest(ExceptionTests, TestSameStrAndUnicodeMsg)
Georg Brandlcdcede62006-05-30 08:47:19 +0000576
577if __name__ == '__main__':
578 test_main()