blob: 85b21a8d4791ec25e683a00d674fd1680dc5c2a8 [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
Brett Cannon672237d2008-09-09 00:49:16 +00007import warnings
Tim Peters80dc76e2006-06-07 06:57:51 +00008
Brett Cannon672237d2008-09-09 00:49:16 +00009from test.test_support import TESTFN, unlink, run_unittest, captured_output
Brett Cannon229cee22007-05-05 01:34:02 +000010from test.test_pep352 import ignore_message_warning
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:
20 import exceptions
21 reload(exceptions)
22 except ImportError, e:
23 self.fail("reloading exceptions: %s" % e)
Jeremy Hylton56c807d2000-06-20 18:52:57 +000024
Georg Brandlcdcede62006-05-30 08:47:19 +000025 def raise_catch(self, exc, excname):
26 try:
27 raise exc, "spam"
28 except exc, err:
29 buf1 = str(err)
30 try:
31 raise exc("spam")
32 except exc, err:
33 buf2 = str(err)
34 self.assertEquals(buf1, buf2)
35 self.assertEquals(exc.__name__, excname)
Guido van Rossum3bead091992-01-27 17:00:37 +000036
Georg Brandlcdcede62006-05-30 08:47:19 +000037 def testRaising(self):
Tim Petersdd55b0a2006-05-30 23:28:02 +000038 self.raise_catch(AttributeError, "AttributeError")
Georg Brandlcdcede62006-05-30 08:47:19 +000039 self.assertRaises(AttributeError, getattr, sys, "undefined_attribute")
Guido van Rossum3bead091992-01-27 17:00:37 +000040
Georg Brandlcdcede62006-05-30 08:47:19 +000041 self.raise_catch(EOFError, "EOFError")
42 fp = open(TESTFN, 'w')
43 fp.close()
44 fp = open(TESTFN, 'r')
45 savestdin = sys.stdin
46 try:
47 try:
48 sys.stdin = fp
49 x = raw_input()
50 except EOFError:
51 pass
52 finally:
53 sys.stdin = savestdin
54 fp.close()
55 unlink(TESTFN)
Guido van Rossum3bead091992-01-27 17:00:37 +000056
Georg Brandlcdcede62006-05-30 08:47:19 +000057 self.raise_catch(IOError, "IOError")
58 self.assertRaises(IOError, open, 'this file does not exist', 'r')
Guido van Rossum3bead091992-01-27 17:00:37 +000059
Georg Brandlcdcede62006-05-30 08:47:19 +000060 self.raise_catch(ImportError, "ImportError")
61 self.assertRaises(ImportError, __import__, "undefined_module")
Guido van Rossum3bead091992-01-27 17:00:37 +000062
Georg Brandlcdcede62006-05-30 08:47:19 +000063 self.raise_catch(IndexError, "IndexError")
64 x = []
65 self.assertRaises(IndexError, x.__getitem__, 10)
Guido van Rossum3bead091992-01-27 17:00:37 +000066
Georg Brandlcdcede62006-05-30 08:47:19 +000067 self.raise_catch(KeyError, "KeyError")
68 x = {}
69 self.assertRaises(KeyError, x.__getitem__, 'key')
Guido van Rossum3bead091992-01-27 17:00:37 +000070
Georg Brandlcdcede62006-05-30 08:47:19 +000071 self.raise_catch(KeyboardInterrupt, "KeyboardInterrupt")
Guido van Rossum3bead091992-01-27 17:00:37 +000072
Georg Brandlcdcede62006-05-30 08:47:19 +000073 self.raise_catch(MemoryError, "MemoryError")
Guido van Rossum3bead091992-01-27 17:00:37 +000074
Georg Brandlcdcede62006-05-30 08:47:19 +000075 self.raise_catch(NameError, "NameError")
76 try: x = undefined_variable
77 except NameError: pass
Guido van Rossum3bead091992-01-27 17:00:37 +000078
Georg Brandlcdcede62006-05-30 08:47:19 +000079 self.raise_catch(OverflowError, "OverflowError")
80 x = 1
81 for dummy in range(128):
82 x += x # this simply shouldn't blow up
Guido van Rossum3bead091992-01-27 17:00:37 +000083
Georg Brandlcdcede62006-05-30 08:47:19 +000084 self.raise_catch(RuntimeError, "RuntimeError")
Guido van Rossum3bead091992-01-27 17:00:37 +000085
Georg Brandlcdcede62006-05-30 08:47:19 +000086 self.raise_catch(SyntaxError, "SyntaxError")
87 try: exec '/\n'
88 except SyntaxError: pass
Guido van Rossum3bead091992-01-27 17:00:37 +000089
Georg Brandlcdcede62006-05-30 08:47:19 +000090 self.raise_catch(IndentationError, "IndentationError")
Fred Drake72e48bd2000-09-08 16:32:34 +000091
Georg Brandlcdcede62006-05-30 08:47:19 +000092 self.raise_catch(TabError, "TabError")
93 # can only be tested under -tt, and is the only test for -tt
94 #try: compile("try:\n\t1/0\n \t1/0\nfinally:\n pass\n", '<string>', 'exec')
95 #except TabError: pass
96 #else: self.fail("TabError not raised")
Fred Drake72e48bd2000-09-08 16:32:34 +000097
Georg Brandlcdcede62006-05-30 08:47:19 +000098 self.raise_catch(SystemError, "SystemError")
Fred Drake72e48bd2000-09-08 16:32:34 +000099
Georg Brandlcdcede62006-05-30 08:47:19 +0000100 self.raise_catch(SystemExit, "SystemExit")
101 self.assertRaises(SystemExit, sys.exit, 0)
Fred Drake85f36392000-07-11 17:53:00 +0000102
Georg Brandlcdcede62006-05-30 08:47:19 +0000103 self.raise_catch(TypeError, "TypeError")
104 try: [] + ()
105 except TypeError: pass
Fred Drake85f36392000-07-11 17:53:00 +0000106
Georg Brandlcdcede62006-05-30 08:47:19 +0000107 self.raise_catch(ValueError, "ValueError")
108 self.assertRaises(ValueError, chr, 10000)
Guido van Rossum3bead091992-01-27 17:00:37 +0000109
Georg Brandlcdcede62006-05-30 08:47:19 +0000110 self.raise_catch(ZeroDivisionError, "ZeroDivisionError")
111 try: x = 1/0
112 except ZeroDivisionError: pass
Guido van Rossum3bead091992-01-27 17:00:37 +0000113
Georg Brandlcdcede62006-05-30 08:47:19 +0000114 self.raise_catch(Exception, "Exception")
115 try: x = 1/0
116 except Exception, e: pass
Guido van Rossum3bead091992-01-27 17:00:37 +0000117
Georg Brandlcdcede62006-05-30 08:47:19 +0000118 def testSyntaxErrorMessage(self):
Neal Norwitze152aab2006-06-02 04:45:53 +0000119 # make sure the right exception message is raised for each of
120 # these code fragments
Guido van Rossum3bead091992-01-27 17:00:37 +0000121
Georg Brandlcdcede62006-05-30 08:47:19 +0000122 def ckmsg(src, msg):
123 try:
124 compile(src, '<fragment>', 'exec')
125 except SyntaxError, e:
126 if e.msg != msg:
127 self.fail("expected %s, got %s" % (msg, e.msg))
128 else:
129 self.fail("failed to get expected SyntaxError")
Guido van Rossum3bead091992-01-27 17:00:37 +0000130
Georg Brandlcdcede62006-05-30 08:47:19 +0000131 s = '''while 1:
132 try:
133 pass
134 finally:
135 continue'''
Barry Warsaw992cb8a2000-05-25 23:16:54 +0000136
Georg Brandlcdcede62006-05-30 08:47:19 +0000137 if not sys.platform.startswith('java'):
138 ckmsg(s, "'continue' not supported inside 'finally' clause")
Jeremy Hyltonede049b2001-09-26 20:01:13 +0000139
Georg Brandlcdcede62006-05-30 08:47:19 +0000140 s = '''if 1:
141 try:
142 continue
143 except:
144 pass'''
Jeremy Hyltonede049b2001-09-26 20:01:13 +0000145
Georg Brandlcdcede62006-05-30 08:47:19 +0000146 ckmsg(s, "'continue' not properly in loop")
147 ckmsg("continue\n", "'continue' not properly in loop")
Jeremy Hyltonede049b2001-09-26 20:01:13 +0000148
Georg Brandlcdcede62006-05-30 08:47:19 +0000149 def testSettingException(self):
Neal Norwitze152aab2006-06-02 04:45:53 +0000150 # test that setting an exception at the C level works even if the
151 # exception object can't be constructed.
Finn Bockaa3dc452001-12-08 10:15:48 +0000152
Georg Brandlcdcede62006-05-30 08:47:19 +0000153 class BadException:
154 def __init__(self_):
155 raise RuntimeError, "can't instantiate BadException"
Jeremy Hyltonede049b2001-09-26 20:01:13 +0000156
Georg Brandlcdcede62006-05-30 08:47:19 +0000157 def test_capi1():
158 import _testcapi
159 try:
160 _testcapi.raise_exception(BadException, 1)
161 except TypeError, err:
162 exc, err, tb = sys.exc_info()
163 co = tb.tb_frame.f_code
164 self.assertEquals(co.co_name, "test_capi1")
165 self.assert_(co.co_filename.endswith('test_exceptions'+os.extsep+'py'))
166 else:
167 self.fail("Expected exception")
Richard Jones7b9558d2006-05-27 12:29:24 +0000168
Georg Brandlcdcede62006-05-30 08:47:19 +0000169 def test_capi2():
170 import _testcapi
171 try:
172 _testcapi.raise_exception(BadException, 0)
173 except RuntimeError, err:
174 exc, err, tb = sys.exc_info()
175 co = tb.tb_frame.f_code
176 self.assertEquals(co.co_name, "__init__")
177 self.assert_(co.co_filename.endswith('test_exceptions'+os.extsep+'py'))
178 co2 = tb.tb_frame.f_back.f_code
179 self.assertEquals(co2.co_name, "test_capi2")
180 else:
181 self.fail("Expected exception")
Richard Jones7b9558d2006-05-27 12:29:24 +0000182
Georg Brandlcdcede62006-05-30 08:47:19 +0000183 if not sys.platform.startswith('java'):
184 test_capi1()
185 test_capi2()
Georg Brandl05f97bf2006-05-30 07:13:29 +0000186
Thomas Hellerdf08f0b2006-10-27 18:31:36 +0000187 def test_WindowsError(self):
188 try:
189 WindowsError
190 except NameError:
191 pass
192 else:
193 self.failUnlessEqual(str(WindowsError(1001)),
194 "1001")
195 self.failUnlessEqual(str(WindowsError(1001, "message")),
196 "[Error 1001] message")
197 self.failUnlessEqual(WindowsError(1001, "message").errno, 22)
198 self.failUnlessEqual(WindowsError(1001, "message").winerror, 1001)
199
Georg Brandlcdcede62006-05-30 08:47:19 +0000200 def testAttributes(self):
Neal Norwitze152aab2006-06-02 04:45:53 +0000201 # test that exception attributes are happy
Tim Petersdd55b0a2006-05-30 23:28:02 +0000202
Georg Brandlcdcede62006-05-30 08:47:19 +0000203 exceptionList = [
Georg Brandle08940e2006-06-01 13:00:49 +0000204 (BaseException, (), {'message' : '', 'args' : ()}),
205 (BaseException, (1, ), {'message' : 1, 'args' : (1,)}),
206 (BaseException, ('foo',),
207 {'message' : 'foo', 'args' : ('foo',)}),
208 (BaseException, ('foo', 1),
209 {'message' : '', 'args' : ('foo', 1)}),
210 (SystemExit, ('foo',),
211 {'message' : 'foo', 'args' : ('foo',), 'code' : 'foo'}),
212 (IOError, ('foo',),
Georg Brandl3267d282006-09-30 09:03:42 +0000213 {'message' : 'foo', 'args' : ('foo',), 'filename' : None,
214 'errno' : None, 'strerror' : None}),
Georg Brandle08940e2006-06-01 13:00:49 +0000215 (IOError, ('foo', 'bar'),
Georg Brandl3267d282006-09-30 09:03:42 +0000216 {'message' : '', 'args' : ('foo', 'bar'), 'filename' : None,
217 'errno' : 'foo', 'strerror' : 'bar'}),
Georg Brandle08940e2006-06-01 13:00:49 +0000218 (IOError, ('foo', 'bar', 'baz'),
Georg Brandl3267d282006-09-30 09:03:42 +0000219 {'message' : '', 'args' : ('foo', 'bar'), 'filename' : 'baz',
220 'errno' : 'foo', 'strerror' : 'bar'}),
221 (IOError, ('foo', 'bar', 'baz', 'quux'),
222 {'message' : '', 'args' : ('foo', 'bar', 'baz', 'quux')}),
Georg Brandle08940e2006-06-01 13:00:49 +0000223 (EnvironmentError, ('errnoStr', 'strErrorStr', 'filenameStr'),
224 {'message' : '', 'args' : ('errnoStr', 'strErrorStr'),
225 'strerror' : 'strErrorStr', 'errno' : 'errnoStr',
226 'filename' : 'filenameStr'}),
227 (EnvironmentError, (1, 'strErrorStr', 'filenameStr'),
228 {'message' : '', 'args' : (1, 'strErrorStr'), 'errno' : 1,
229 'strerror' : 'strErrorStr', 'filename' : 'filenameStr'}),
Brett Cannonf8267df2007-02-28 18:15:00 +0000230 (SyntaxError, (), {'message' : '', 'msg' : None, 'text' : None,
231 'filename' : None, 'lineno' : None, 'offset' : None,
232 'print_file_and_line' : None}),
Georg Brandle08940e2006-06-01 13:00:49 +0000233 (SyntaxError, ('msgStr',),
234 {'message' : 'msgStr', 'args' : ('msgStr',), 'text' : None,
235 'print_file_and_line' : None, 'msg' : 'msgStr',
236 'filename' : None, 'lineno' : None, 'offset' : None}),
237 (SyntaxError, ('msgStr', ('filenameStr', 'linenoStr', 'offsetStr',
238 'textStr')),
239 {'message' : '', 'offset' : 'offsetStr', 'text' : 'textStr',
240 'args' : ('msgStr', ('filenameStr', 'linenoStr',
241 'offsetStr', 'textStr')),
242 'print_file_and_line' : None, 'msg' : 'msgStr',
243 'filename' : 'filenameStr', 'lineno' : 'linenoStr'}),
244 (SyntaxError, ('msgStr', 'filenameStr', 'linenoStr', 'offsetStr',
245 'textStr', 'print_file_and_lineStr'),
246 {'message' : '', 'text' : None,
247 'args' : ('msgStr', 'filenameStr', 'linenoStr', 'offsetStr',
248 'textStr', 'print_file_and_lineStr'),
249 'print_file_and_line' : None, 'msg' : 'msgStr',
250 'filename' : None, 'lineno' : None, 'offset' : None}),
251 (UnicodeError, (), {'message' : '', 'args' : (),}),
Georg Brandl38f62372006-09-06 06:50:05 +0000252 (UnicodeEncodeError, ('ascii', u'a', 0, 1, 'ordinal not in range'),
253 {'message' : '', 'args' : ('ascii', u'a', 0, 1,
254 'ordinal not in range'),
255 'encoding' : 'ascii', 'object' : u'a',
256 'start' : 0, 'reason' : 'ordinal not in range'}),
257 (UnicodeDecodeError, ('ascii', '\xff', 0, 1, 'ordinal not in range'),
Georg Brandle08940e2006-06-01 13:00:49 +0000258 {'message' : '', 'args' : ('ascii', '\xff', 0, 1,
Georg Brandl38f62372006-09-06 06:50:05 +0000259 'ordinal not in range'),
Georg Brandle08940e2006-06-01 13:00:49 +0000260 'encoding' : 'ascii', 'object' : '\xff',
Georg Brandl38f62372006-09-06 06:50:05 +0000261 'start' : 0, 'reason' : 'ordinal not in range'}),
Georg Brandle08940e2006-06-01 13:00:49 +0000262 (UnicodeTranslateError, (u"\u3042", 0, 1, "ouch"),
263 {'message' : '', 'args' : (u'\u3042', 0, 1, 'ouch'),
264 'object' : u'\u3042', 'reason' : 'ouch',
265 'start' : 0, 'end' : 1}),
266 ]
Georg Brandlcdcede62006-05-30 08:47:19 +0000267 try:
268 exceptionList.append(
Georg Brandle08940e2006-06-01 13:00:49 +0000269 (WindowsError, (1, 'strErrorStr', 'filenameStr'),
270 {'message' : '', 'args' : (1, 'strErrorStr'),
271 'strerror' : 'strErrorStr', 'winerror' : 1,
272 'errno' : 22, 'filename' : 'filenameStr'})
273 )
Tim Peters80dc76e2006-06-07 06:57:51 +0000274 except NameError:
275 pass
Georg Brandlcdcede62006-05-30 08:47:19 +0000276
Brett Cannon672237d2008-09-09 00:49:16 +0000277 with warnings.catch_warnings():
Brett Cannon229cee22007-05-05 01:34:02 +0000278 ignore_message_warning()
279 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
Georg Brandld7e9f602007-08-21 06:03:43 +0000286 self.assertEquals(type(e).__module__, 'exceptions')
Brett Cannon229cee22007-05-05 01:34:02 +0000287 # 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
Brett Cannon229cee22007-05-05 01:34:02 +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,
Brett Cannonb13f70d2007-11-03 06:47:02 +0000303 'pickled "%r", attribute "%s"' %
Brett Cannon229cee22007-05-05 01:34:02 +0000304 (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")
311 with warnings.catch_warnings(record=True) as w:
312 self.assertEquals(exc.message, "foo")
313 self.assertEquals(len(w), 1)
314 self.assertEquals(w[0].category, DeprecationWarning)
315 self.assertEquals(
316 str(w[0].message),
317 "BaseException.message has been deprecated as of Python 2.6")
318
319
320 def testRegularMessageAttribute(self):
321 # Accessing BaseException.message after explicitly setting a value
322 # for it does not trigger a deprecation warning.
323 exc = BaseException("foo")
324 exc.message = "bar"
325 with warnings.catch_warnings(record=True) as w:
326 self.assertEquals(exc.message, "bar")
327 self.assertEquals(len(w), 0)
328 # Deleting the message is supported, too.
329 del exc.message
330 self.assertRaises(AttributeError, getattr, exc, "message")
331
332 def testPickleMessageAttribute(self):
333 # Pickling with message attribute must work, as well.
334 e = Exception("foo")
335 f = Exception("foo")
336 f.message = "bar"
337 for p in pickle, cPickle:
338 ep = p.loads(p.dumps(e))
339 with warnings.catch_warnings():
340 ignore_message_warning()
341 self.assertEqual(ep.message, "foo")
342 fp = p.loads(p.dumps(f))
343 self.assertEqual(fp.message, "bar")
344
Brett Cannone05e6b02007-01-29 04:41:44 +0000345 def testSlicing(self):
346 # Test that you can slice an exception directly instead of requiring
347 # going through the 'args' attribute.
348 args = (1, 2, 3)
349 exc = BaseException(*args)
350 self.failUnlessEqual(exc[:], args)
351
Georg Brandlcdcede62006-05-30 08:47:19 +0000352 def testKeywordArgs(self):
Neal Norwitze152aab2006-06-02 04:45:53 +0000353 # test that builtin exception don't take keyword args,
354 # but user-defined subclasses can if they want
Georg Brandlcdcede62006-05-30 08:47:19 +0000355 self.assertRaises(TypeError, BaseException, a=1)
Georg Brandle08940e2006-06-01 13:00:49 +0000356
Georg Brandlcdcede62006-05-30 08:47:19 +0000357 class DerivedException(BaseException):
358 def __init__(self, fancy_arg):
359 BaseException.__init__(self)
360 self.fancy_arg = fancy_arg
361
362 x = DerivedException(fancy_arg=42)
363 self.assertEquals(x.fancy_arg, 42)
364
Armin Rigo53c1692f2006-06-21 21:58:50 +0000365 def testInfiniteRecursion(self):
366 def f():
367 return f()
368 self.assertRaises(RuntimeError, f)
369
370 def g():
371 try:
372 return g()
373 except ValueError:
374 return -1
Antoine Pitrou0668c622008-08-26 22:42:08 +0000375
376 # The test prints an unraisable recursion error when
377 # doing "except ValueError", this is because subclass
378 # checking has recursion checking too.
379 with captured_output("stderr"):
380 try:
381 g()
382 except RuntimeError:
383 pass
384 except:
385 self.fail("Should have raised KeyError")
386 else:
387 self.fail("Should have raised KeyError")
Armin Rigo53c1692f2006-06-21 21:58:50 +0000388
Brett Cannonca2ca792006-09-09 07:11:46 +0000389 def testUnicodeStrUsage(self):
390 # Make sure both instances and classes have a str and unicode
391 # representation.
392 self.failUnless(str(Exception))
393 self.failUnless(unicode(Exception))
394 self.failUnless(str(Exception('a')))
395 self.failUnless(unicode(Exception(u'a')))
Nick Coghlan524b7772008-07-08 14:08:04 +0000396 self.failUnless(unicode(Exception(u'\xe1')))
Brett Cannonca2ca792006-09-09 07:11:46 +0000397
Eric Smith66807852010-02-24 14:27:37 +0000398 def testUnicodeChangeAttributes(self):
399 # See issue 7309. This was a crasher.
400
401 u = UnicodeEncodeError('baz', u'xxxxx', 1, 5, 'foo')
402 self.assertEqual(str(u), "'baz' codec can't encode characters in position 1-4: foo")
403 u.end = 2
404 self.assertEqual(str(u), "'baz' codec can't encode character u'\\x78' in position 1: foo")
405 u.end = 5
406 u.reason = 0x345345345345345345
407 self.assertEqual(str(u), "'baz' codec can't encode characters in position 1-4: 965230951443685724997")
408 u.encoding = 4000
409 self.assertEqual(str(u), "'4000' codec can't encode characters in position 1-4: 965230951443685724997")
410 u.start = 1000
411 self.assertEqual(str(u), "'4000' codec can't encode characters in position 1000-4: 965230951443685724997")
412
413 u = UnicodeDecodeError('baz', 'xxxxx', 1, 5, 'foo')
414 self.assertEqual(str(u), "'baz' codec can't decode bytes in position 1-4: foo")
415 u.end = 2
416 self.assertEqual(str(u), "'baz' codec can't decode byte 0x78 in position 1: foo")
417 u.end = 5
418 u.reason = 0x345345345345345345
419 self.assertEqual(str(u), "'baz' codec can't decode bytes in position 1-4: 965230951443685724997")
420 u.encoding = 4000
421 self.assertEqual(str(u), "'4000' codec can't decode bytes in position 1-4: 965230951443685724997")
422 u.start = 1000
423 self.assertEqual(str(u), "'4000' codec can't decode bytes in position 1000-4: 965230951443685724997")
424
425 u = UnicodeTranslateError(u'xxxx', 1, 5, 'foo')
426 self.assertEqual(str(u), "can't translate characters in position 1-4: foo")
427 u.end = 2
428 self.assertEqual(str(u), "can't translate character u'\\x78' in position 1: foo")
429 u.end = 5
430 u.reason = 0x345345345345345345
431 self.assertEqual(str(u), "can't translate characters in position 1-4: 965230951443685724997")
432 u.start = 1000
433 self.assertEqual(str(u), "can't translate characters in position 1000-4: 965230951443685724997")
434
Amaury Forgeot d'Arc246daed2008-07-31 00:42:16 +0000435 def test_badisinstance(self):
436 # Bug #2542: if issubclass(e, MyException) raises an exception,
437 # it should be ignored
438 class Meta(type):
439 def __subclasscheck__(cls, subclass):
440 raise ValueError()
441
442 class MyException(Exception):
443 __metaclass__ = Meta
444 pass
445
446 with captured_output("stderr") as stderr:
447 try:
448 raise KeyError()
449 except MyException, e:
450 self.fail("exception should not be a MyException")
451 except KeyError:
452 pass
453 except:
Antoine Pitrou0668c622008-08-26 22:42:08 +0000454 self.fail("Should have raised KeyError")
Amaury Forgeot d'Arc246daed2008-07-31 00:42:16 +0000455 else:
Antoine Pitrou0668c622008-08-26 22:42:08 +0000456 self.fail("Should have raised KeyError")
457
458 with captured_output("stderr") as stderr:
459 def g():
460 try:
461 return g()
462 except RuntimeError:
463 return sys.exc_info()
464 e, v, tb = g()
465 self.assert_(e is RuntimeError, e)
466 self.assert_("maximum recursion depth exceeded" in str(v), v)
467
Brett Cannonca2ca792006-09-09 07:11:46 +0000468
Ezio Melottie7482382009-12-24 22:32:25 +0000469
470# Helper class used by TestSameStrAndUnicodeMsg
471class ExcWithOverriddenStr(Exception):
472 """Subclass of Exception that accepts a keyword 'msg' arg that is
473 returned by __str__. 'msg' won't be included in self.args"""
474 def __init__(self, *args, **kwargs):
475 self.msg = kwargs.pop('msg') # msg should always be present
476 super(ExcWithOverriddenStr, self).__init__(*args, **kwargs)
477 def __str__(self):
478 return self.msg
479
480
481class TestSameStrAndUnicodeMsg(unittest.TestCase):
482 """unicode(err) should return the same message of str(err). See #6108"""
483
484 def check_same_msg(self, exc, msg):
485 """Helper function that checks if str(exc) == unicode(exc) == msg"""
486 self.assertEqual(str(exc), msg)
487 self.assertEqual(str(exc), unicode(exc))
488
489 def test_builtin_exceptions(self):
490 """Check same msg for built-in exceptions"""
491 # These exceptions implement a __str__ method that uses the args
492 # to create a better error message. unicode(e) should return the same
493 # message.
494 exceptions = [
495 SyntaxError('invalid syntax', ('<string>', 1, 3, '2+*3')),
496 IOError(2, 'No such file or directory'),
497 KeyError('both should have the same quotes'),
498 UnicodeDecodeError('ascii', '\xc3\xa0', 0, 1,
499 'ordinal not in range(128)'),
500 UnicodeEncodeError('ascii', u'\u1234', 0, 1,
501 'ordinal not in range(128)')
502 ]
503 for exception in exceptions:
504 self.assertEqual(str(exception), unicode(exception))
505
506 def test_0_args(self):
507 """Check same msg for Exception with 0 args"""
508 # str() and unicode() on an Exception with no args should return an
509 # empty string
510 self.check_same_msg(Exception(), '')
511
512 def test_0_args_with_overridden___str__(self):
513 """Check same msg for exceptions with 0 args and overridden __str__"""
514 # str() and unicode() on an exception with overridden __str__ that
515 # returns an ascii-only string should return the same string
516 for msg in ('foo', u'foo'):
517 self.check_same_msg(ExcWithOverriddenStr(msg=msg), msg)
518
519 # if __str__ returns a non-ascii unicode string str() should fail
520 # but unicode() should return the unicode string
521 e = ExcWithOverriddenStr(msg=u'f\xf6\xf6') # no args
522 self.assertRaises(UnicodeEncodeError, str, e)
523 self.assertEqual(unicode(e), u'f\xf6\xf6')
524
525 def test_1_arg(self):
526 """Check same msg for Exceptions with 1 arg"""
527 for arg in ('foo', u'foo'):
528 self.check_same_msg(Exception(arg), arg)
529
530 # if __str__ is not overridden and self.args[0] is a non-ascii unicode
531 # string, str() should try to return str(self.args[0]) and fail.
532 # unicode() should return unicode(self.args[0]) and succeed.
533 e = Exception(u'f\xf6\xf6')
534 self.assertRaises(UnicodeEncodeError, str, e)
535 self.assertEqual(unicode(e), u'f\xf6\xf6')
536
537 def test_1_arg_with_overridden___str__(self):
538 """Check same msg for exceptions with overridden __str__ and 1 arg"""
539 # when __str__ is overridden and __unicode__ is not implemented
540 # unicode(e) returns the same as unicode(e.__str__()).
541 for msg in ('foo', u'foo'):
542 self.check_same_msg(ExcWithOverriddenStr('arg', msg=msg), msg)
543
544 # if __str__ returns a non-ascii unicode string, str() should fail
545 # but unicode() should succeed.
546 e = ExcWithOverriddenStr('arg', msg=u'f\xf6\xf6') # 1 arg
547 self.assertRaises(UnicodeEncodeError, str, e)
548 self.assertEqual(unicode(e), u'f\xf6\xf6')
549
550 def test_many_args(self):
551 """Check same msg for Exceptions with many args"""
552 argslist = [
553 (3, 'foo'),
554 (1, u'foo', 'bar'),
555 (4, u'f\xf6\xf6', u'bar', 'baz')
556 ]
557 # both str() and unicode() should return a repr() of the args
558 for args in argslist:
559 self.check_same_msg(Exception(*args), repr(args))
560
561 def test_many_args_with_overridden___str__(self):
562 """Check same msg for exceptions with overridden __str__ and many args"""
563 # if __str__ returns an ascii string / ascii unicode string
564 # both str() and unicode() should succeed
565 for msg in ('foo', u'foo'):
566 e = ExcWithOverriddenStr('arg1', u'arg2', u'f\xf6\xf6', msg=msg)
567 self.check_same_msg(e, msg)
568
569 # if __str__ returns a non-ascii unicode string, str() should fail
570 # but unicode() should succeed
571 e = ExcWithOverriddenStr('arg1', u'f\xf6\xf6', u'arg3', # 3 args
572 msg=u'f\xf6\xf6')
573 self.assertRaises(UnicodeEncodeError, str, e)
574 self.assertEqual(unicode(e), u'f\xf6\xf6')
575
576
Georg Brandlcdcede62006-05-30 08:47:19 +0000577def test_main():
Ezio Melottie7482382009-12-24 22:32:25 +0000578 run_unittest(ExceptionTests, TestSameStrAndUnicodeMsg)
Georg Brandlcdcede62006-05-30 08:47:19 +0000579
580if __name__ == '__main__':
581 test_main()