blob: 43de4de9aa3c775b24538443aae3de7d95abfb27 [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
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")
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
Ezio Melotti38a58002010-08-02 03:14:27 +0000332 @ignore_deprecation_warnings
Georg Brandl89971032009-09-16 20:34:51 +0000333 def testPickleMessageAttribute(self):
334 # Pickling with message attribute must work, as well.
335 e = Exception("foo")
336 f = Exception("foo")
337 f.message = "bar"
338 for p in pickle, cPickle:
339 ep = p.loads(p.dumps(e))
Ezio Melotti38a58002010-08-02 03:14:27 +0000340 self.assertEqual(ep.message, "foo")
Georg Brandl89971032009-09-16 20:34:51 +0000341 fp = p.loads(p.dumps(f))
342 self.assertEqual(fp.message, "bar")
343
Ezio Melotti38a58002010-08-02 03:14:27 +0000344 @ignore_deprecation_warnings
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)
Ezio Melotti38a58002010-08-02 03:14:27 +0000351 self.assertEqual(exc.args[:], args)
Brett Cannone05e6b02007-01-29 04:41:44 +0000352
Georg Brandlcdcede62006-05-30 08:47:19 +0000353 def testKeywordArgs(self):
Neal Norwitze152aab2006-06-02 04:45:53 +0000354 # test that builtin exception don't take keyword args,
355 # but user-defined subclasses can if they want
Georg Brandlcdcede62006-05-30 08:47:19 +0000356 self.assertRaises(TypeError, BaseException, a=1)
Georg Brandle08940e2006-06-01 13:00:49 +0000357
Georg Brandlcdcede62006-05-30 08:47:19 +0000358 class DerivedException(BaseException):
359 def __init__(self, fancy_arg):
360 BaseException.__init__(self)
361 self.fancy_arg = fancy_arg
362
363 x = DerivedException(fancy_arg=42)
364 self.assertEquals(x.fancy_arg, 42)
365
Armin Rigo53c1692f2006-06-21 21:58:50 +0000366 def testInfiniteRecursion(self):
367 def f():
368 return f()
369 self.assertRaises(RuntimeError, f)
370
371 def g():
372 try:
373 return g()
374 except ValueError:
375 return -1
Antoine Pitrou0668c622008-08-26 22:42:08 +0000376
377 # The test prints an unraisable recursion error when
378 # doing "except ValueError", this is because subclass
379 # checking has recursion checking too.
380 with captured_output("stderr"):
381 try:
382 g()
383 except RuntimeError:
384 pass
385 except:
386 self.fail("Should have raised KeyError")
387 else:
388 self.fail("Should have raised KeyError")
Armin Rigo53c1692f2006-06-21 21:58:50 +0000389
Brett Cannonca2ca792006-09-09 07:11:46 +0000390 def testUnicodeStrUsage(self):
391 # Make sure both instances and classes have a str and unicode
392 # representation.
393 self.failUnless(str(Exception))
394 self.failUnless(unicode(Exception))
395 self.failUnless(str(Exception('a')))
396 self.failUnless(unicode(Exception(u'a')))
Nick Coghlan524b7772008-07-08 14:08:04 +0000397 self.failUnless(unicode(Exception(u'\xe1')))
Brett Cannonca2ca792006-09-09 07:11:46 +0000398
Eric Smith66807852010-02-24 14:27:37 +0000399 def testUnicodeChangeAttributes(self):
400 # See issue 7309. This was a crasher.
401
402 u = UnicodeEncodeError('baz', u'xxxxx', 1, 5, 'foo')
403 self.assertEqual(str(u), "'baz' codec can't encode characters in position 1-4: foo")
404 u.end = 2
405 self.assertEqual(str(u), "'baz' codec can't encode character u'\\x78' in position 1: foo")
406 u.end = 5
407 u.reason = 0x345345345345345345
408 self.assertEqual(str(u), "'baz' codec can't encode characters in position 1-4: 965230951443685724997")
409 u.encoding = 4000
410 self.assertEqual(str(u), "'4000' codec can't encode characters in position 1-4: 965230951443685724997")
411 u.start = 1000
412 self.assertEqual(str(u), "'4000' codec can't encode characters in position 1000-4: 965230951443685724997")
413
414 u = UnicodeDecodeError('baz', 'xxxxx', 1, 5, 'foo')
415 self.assertEqual(str(u), "'baz' codec can't decode bytes in position 1-4: foo")
416 u.end = 2
417 self.assertEqual(str(u), "'baz' codec can't decode byte 0x78 in position 1: foo")
418 u.end = 5
419 u.reason = 0x345345345345345345
420 self.assertEqual(str(u), "'baz' codec can't decode bytes in position 1-4: 965230951443685724997")
421 u.encoding = 4000
422 self.assertEqual(str(u), "'4000' codec can't decode bytes in position 1-4: 965230951443685724997")
423 u.start = 1000
424 self.assertEqual(str(u), "'4000' codec can't decode bytes in position 1000-4: 965230951443685724997")
425
426 u = UnicodeTranslateError(u'xxxx', 1, 5, 'foo')
427 self.assertEqual(str(u), "can't translate characters in position 1-4: foo")
428 u.end = 2
429 self.assertEqual(str(u), "can't translate character u'\\x78' in position 1: foo")
430 u.end = 5
431 u.reason = 0x345345345345345345
432 self.assertEqual(str(u), "can't translate characters in position 1-4: 965230951443685724997")
433 u.start = 1000
434 self.assertEqual(str(u), "can't translate characters in position 1000-4: 965230951443685724997")
435
Amaury Forgeot d'Arc246daed2008-07-31 00:42:16 +0000436 def test_badisinstance(self):
437 # Bug #2542: if issubclass(e, MyException) raises an exception,
438 # it should be ignored
439 class Meta(type):
440 def __subclasscheck__(cls, subclass):
441 raise ValueError()
442
443 class MyException(Exception):
444 __metaclass__ = Meta
445 pass
446
447 with captured_output("stderr") as stderr:
448 try:
449 raise KeyError()
450 except MyException, e:
451 self.fail("exception should not be a MyException")
452 except KeyError:
453 pass
454 except:
Antoine Pitrou0668c622008-08-26 22:42:08 +0000455 self.fail("Should have raised KeyError")
Amaury Forgeot d'Arc246daed2008-07-31 00:42:16 +0000456 else:
Antoine Pitrou0668c622008-08-26 22:42:08 +0000457 self.fail("Should have raised KeyError")
458
459 with captured_output("stderr") as stderr:
460 def g():
461 try:
462 return g()
463 except RuntimeError:
464 return sys.exc_info()
465 e, v, tb = g()
466 self.assert_(e is RuntimeError, e)
467 self.assert_("maximum recursion depth exceeded" in str(v), v)
468
Brett Cannonca2ca792006-09-09 07:11:46 +0000469
Ezio Melottie7482382009-12-24 22:32:25 +0000470
471# Helper class used by TestSameStrAndUnicodeMsg
472class ExcWithOverriddenStr(Exception):
473 """Subclass of Exception that accepts a keyword 'msg' arg that is
474 returned by __str__. 'msg' won't be included in self.args"""
475 def __init__(self, *args, **kwargs):
476 self.msg = kwargs.pop('msg') # msg should always be present
477 super(ExcWithOverriddenStr, self).__init__(*args, **kwargs)
478 def __str__(self):
479 return self.msg
480
481
482class TestSameStrAndUnicodeMsg(unittest.TestCase):
483 """unicode(err) should return the same message of str(err). See #6108"""
484
485 def check_same_msg(self, exc, msg):
486 """Helper function that checks if str(exc) == unicode(exc) == msg"""
487 self.assertEqual(str(exc), msg)
488 self.assertEqual(str(exc), unicode(exc))
489
490 def test_builtin_exceptions(self):
491 """Check same msg for built-in exceptions"""
492 # These exceptions implement a __str__ method that uses the args
493 # to create a better error message. unicode(e) should return the same
494 # message.
495 exceptions = [
496 SyntaxError('invalid syntax', ('<string>', 1, 3, '2+*3')),
497 IOError(2, 'No such file or directory'),
498 KeyError('both should have the same quotes'),
499 UnicodeDecodeError('ascii', '\xc3\xa0', 0, 1,
500 'ordinal not in range(128)'),
501 UnicodeEncodeError('ascii', u'\u1234', 0, 1,
502 'ordinal not in range(128)')
503 ]
504 for exception in exceptions:
505 self.assertEqual(str(exception), unicode(exception))
506
507 def test_0_args(self):
508 """Check same msg for Exception with 0 args"""
509 # str() and unicode() on an Exception with no args should return an
510 # empty string
511 self.check_same_msg(Exception(), '')
512
513 def test_0_args_with_overridden___str__(self):
514 """Check same msg for exceptions with 0 args and overridden __str__"""
515 # str() and unicode() on an exception with overridden __str__ that
516 # returns an ascii-only string should return the same string
517 for msg in ('foo', u'foo'):
518 self.check_same_msg(ExcWithOverriddenStr(msg=msg), msg)
519
520 # if __str__ returns a non-ascii unicode string str() should fail
521 # but unicode() should return the unicode string
522 e = ExcWithOverriddenStr(msg=u'f\xf6\xf6') # no args
523 self.assertRaises(UnicodeEncodeError, str, e)
524 self.assertEqual(unicode(e), u'f\xf6\xf6')
525
526 def test_1_arg(self):
527 """Check same msg for Exceptions with 1 arg"""
528 for arg in ('foo', u'foo'):
529 self.check_same_msg(Exception(arg), arg)
530
531 # if __str__ is not overridden and self.args[0] is a non-ascii unicode
532 # string, str() should try to return str(self.args[0]) and fail.
533 # unicode() should return unicode(self.args[0]) and succeed.
534 e = Exception(u'f\xf6\xf6')
535 self.assertRaises(UnicodeEncodeError, str, e)
536 self.assertEqual(unicode(e), u'f\xf6\xf6')
537
538 def test_1_arg_with_overridden___str__(self):
539 """Check same msg for exceptions with overridden __str__ and 1 arg"""
540 # when __str__ is overridden and __unicode__ is not implemented
541 # unicode(e) returns the same as unicode(e.__str__()).
542 for msg in ('foo', u'foo'):
543 self.check_same_msg(ExcWithOverriddenStr('arg', msg=msg), msg)
544
545 # if __str__ returns a non-ascii unicode string, str() should fail
546 # but unicode() should succeed.
547 e = ExcWithOverriddenStr('arg', msg=u'f\xf6\xf6') # 1 arg
548 self.assertRaises(UnicodeEncodeError, str, e)
549 self.assertEqual(unicode(e), u'f\xf6\xf6')
550
551 def test_many_args(self):
552 """Check same msg for Exceptions with many args"""
553 argslist = [
554 (3, 'foo'),
555 (1, u'foo', 'bar'),
556 (4, u'f\xf6\xf6', u'bar', 'baz')
557 ]
558 # both str() and unicode() should return a repr() of the args
559 for args in argslist:
560 self.check_same_msg(Exception(*args), repr(args))
561
562 def test_many_args_with_overridden___str__(self):
563 """Check same msg for exceptions with overridden __str__ and many args"""
564 # if __str__ returns an ascii string / ascii unicode string
565 # both str() and unicode() should succeed
566 for msg in ('foo', u'foo'):
567 e = ExcWithOverriddenStr('arg1', u'arg2', u'f\xf6\xf6', msg=msg)
568 self.check_same_msg(e, msg)
569
570 # if __str__ returns a non-ascii unicode string, str() should fail
571 # but unicode() should succeed
572 e = ExcWithOverriddenStr('arg1', u'f\xf6\xf6', u'arg3', # 3 args
573 msg=u'f\xf6\xf6')
574 self.assertRaises(UnicodeEncodeError, str, e)
575 self.assertEqual(unicode(e), u'f\xf6\xf6')
576
577
Georg Brandlcdcede62006-05-30 08:47:19 +0000578def test_main():
Ezio Melottie7482382009-12-24 22:32:25 +0000579 run_unittest(ExceptionTests, TestSameStrAndUnicodeMsg)
Georg Brandlcdcede62006-05-30 08:47:19 +0000580
581if __name__ == '__main__':
582 test_main()