ยปCore Development>Code coverage>Lib/test/test_exceptions.py

Python code coverage for Lib/test/test_exceptions.py

#countcontent
1n/a# Python test set -- part 5, built-in exceptions
2n/a
3n/aimport os
4n/aimport sys
5n/aimport unittest
6n/aimport pickle
7n/aimport weakref
8n/aimport errno
9n/a
10n/afrom test.support import (TESTFN, captured_stderr, check_impl_detail,
11n/a check_warnings, cpython_only, gc_collect, run_unittest,
12n/a no_tracing, unlink, import_module)
13n/a
14n/aclass NaiveException(Exception):
15n/a def __init__(self, x):
16n/a self.x = x
17n/a
18n/aclass SlottedNaiveException(Exception):
19n/a __slots__ = ('x',)
20n/a def __init__(self, x):
21n/a self.x = x
22n/a
23n/aclass BrokenStrException(Exception):
24n/a def __str__(self):
25n/a raise Exception("str() is broken")
26n/a
27n/a# XXX This is not really enough, each *operation* should be tested!
28n/a
29n/aclass ExceptionTests(unittest.TestCase):
30n/a
31n/a def raise_catch(self, exc, excname):
32n/a try:
33n/a raise exc("spam")
34n/a except exc as err:
35n/a buf1 = str(err)
36n/a try:
37n/a raise exc("spam")
38n/a except exc as err:
39n/a buf2 = str(err)
40n/a self.assertEqual(buf1, buf2)
41n/a self.assertEqual(exc.__name__, excname)
42n/a
43n/a def testRaising(self):
44n/a self.raise_catch(AttributeError, "AttributeError")
45n/a self.assertRaises(AttributeError, getattr, sys, "undefined_attribute")
46n/a
47n/a self.raise_catch(EOFError, "EOFError")
48n/a fp = open(TESTFN, 'w')
49n/a fp.close()
50n/a fp = open(TESTFN, 'r')
51n/a savestdin = sys.stdin
52n/a try:
53n/a try:
54n/a import marshal
55n/a marshal.loads(b'')
56n/a except EOFError:
57n/a pass
58n/a finally:
59n/a sys.stdin = savestdin
60n/a fp.close()
61n/a unlink(TESTFN)
62n/a
63n/a self.raise_catch(OSError, "OSError")
64n/a self.assertRaises(OSError, open, 'this file does not exist', 'r')
65n/a
66n/a self.raise_catch(ImportError, "ImportError")
67n/a self.assertRaises(ImportError, __import__, "undefined_module")
68n/a
69n/a self.raise_catch(IndexError, "IndexError")
70n/a x = []
71n/a self.assertRaises(IndexError, x.__getitem__, 10)
72n/a
73n/a self.raise_catch(KeyError, "KeyError")
74n/a x = {}
75n/a self.assertRaises(KeyError, x.__getitem__, 'key')
76n/a
77n/a self.raise_catch(KeyboardInterrupt, "KeyboardInterrupt")
78n/a
79n/a self.raise_catch(MemoryError, "MemoryError")
80n/a
81n/a self.raise_catch(NameError, "NameError")
82n/a try: x = undefined_variable
83n/a except NameError: pass
84n/a
85n/a self.raise_catch(OverflowError, "OverflowError")
86n/a x = 1
87n/a for dummy in range(128):
88n/a x += x # this simply shouldn't blow up
89n/a
90n/a self.raise_catch(RuntimeError, "RuntimeError")
91n/a self.raise_catch(RecursionError, "RecursionError")
92n/a
93n/a self.raise_catch(SyntaxError, "SyntaxError")
94n/a try: exec('/\n')
95n/a except SyntaxError: pass
96n/a
97n/a self.raise_catch(IndentationError, "IndentationError")
98n/a
99n/a self.raise_catch(TabError, "TabError")
100n/a try: compile("try:\n\t1/0\n \t1/0\nfinally:\n pass\n",
101n/a '<string>', 'exec')
102n/a except TabError: pass
103n/a else: self.fail("TabError not raised")
104n/a
105n/a self.raise_catch(SystemError, "SystemError")
106n/a
107n/a self.raise_catch(SystemExit, "SystemExit")
108n/a self.assertRaises(SystemExit, sys.exit, 0)
109n/a
110n/a self.raise_catch(TypeError, "TypeError")
111n/a try: [] + ()
112n/a except TypeError: pass
113n/a
114n/a self.raise_catch(ValueError, "ValueError")
115n/a self.assertRaises(ValueError, chr, 17<<16)
116n/a
117n/a self.raise_catch(ZeroDivisionError, "ZeroDivisionError")
118n/a try: x = 1/0
119n/a except ZeroDivisionError: pass
120n/a
121n/a self.raise_catch(Exception, "Exception")
122n/a try: x = 1/0
123n/a except Exception as e: pass
124n/a
125n/a self.raise_catch(StopAsyncIteration, "StopAsyncIteration")
126n/a
127n/a def testSyntaxErrorMessage(self):
128n/a # make sure the right exception message is raised for each of
129n/a # these code fragments
130n/a
131n/a def ckmsg(src, msg):
132n/a try:
133n/a compile(src, '<fragment>', 'exec')
134n/a except SyntaxError as e:
135n/a if e.msg != msg:
136n/a self.fail("expected %s, got %s" % (msg, e.msg))
137n/a else:
138n/a self.fail("failed to get expected SyntaxError")
139n/a
140n/a s = '''while 1:
141n/a try:
142n/a pass
143n/a finally:
144n/a continue'''
145n/a
146n/a if not sys.platform.startswith('java'):
147n/a ckmsg(s, "'continue' not supported inside 'finally' clause")
148n/a
149n/a s = '''if 1:
150n/a try:
151n/a continue
152n/a except:
153n/a pass'''
154n/a
155n/a ckmsg(s, "'continue' not properly in loop")
156n/a ckmsg("continue\n", "'continue' not properly in loop")
157n/a
158n/a def testSyntaxErrorOffset(self):
159n/a def check(src, lineno, offset):
160n/a with self.assertRaises(SyntaxError) as cm:
161n/a compile(src, '<fragment>', 'exec')
162n/a self.assertEqual(cm.exception.lineno, lineno)
163n/a self.assertEqual(cm.exception.offset, offset)
164n/a
165n/a check('def fact(x):\n\treturn x!\n', 2, 10)
166n/a check('1 +\n', 1, 4)
167n/a check('def spam():\n print(1)\n print(2)', 3, 10)
168n/a check('Python = "Python" +', 1, 20)
169n/a check('Python = "\u1e54\xfd\u0163\u0125\xf2\xf1" +', 1, 20)
170n/a
171n/a @cpython_only
172n/a def testSettingException(self):
173n/a # test that setting an exception at the C level works even if the
174n/a # exception object can't be constructed.
175n/a
176n/a class BadException(Exception):
177n/a def __init__(self_):
178n/a raise RuntimeError("can't instantiate BadException")
179n/a
180n/a class InvalidException:
181n/a pass
182n/a
183n/a def test_capi1():
184n/a import _testcapi
185n/a try:
186n/a _testcapi.raise_exception(BadException, 1)
187n/a except TypeError as err:
188n/a exc, err, tb = sys.exc_info()
189n/a co = tb.tb_frame.f_code
190n/a self.assertEqual(co.co_name, "test_capi1")
191n/a self.assertTrue(co.co_filename.endswith('test_exceptions.py'))
192n/a else:
193n/a self.fail("Expected exception")
194n/a
195n/a def test_capi2():
196n/a import _testcapi
197n/a try:
198n/a _testcapi.raise_exception(BadException, 0)
199n/a except RuntimeError as err:
200n/a exc, err, tb = sys.exc_info()
201n/a co = tb.tb_frame.f_code
202n/a self.assertEqual(co.co_name, "__init__")
203n/a self.assertTrue(co.co_filename.endswith('test_exceptions.py'))
204n/a co2 = tb.tb_frame.f_back.f_code
205n/a self.assertEqual(co2.co_name, "test_capi2")
206n/a else:
207n/a self.fail("Expected exception")
208n/a
209n/a def test_capi3():
210n/a import _testcapi
211n/a self.assertRaises(SystemError, _testcapi.raise_exception,
212n/a InvalidException, 1)
213n/a
214n/a if not sys.platform.startswith('java'):
215n/a test_capi1()
216n/a test_capi2()
217n/a test_capi3()
218n/a
219n/a def test_WindowsError(self):
220n/a try:
221n/a WindowsError
222n/a except NameError:
223n/a pass
224n/a else:
225n/a self.assertIs(WindowsError, OSError)
226n/a self.assertEqual(str(OSError(1001)), "1001")
227n/a self.assertEqual(str(OSError(1001, "message")),
228n/a "[Errno 1001] message")
229n/a # POSIX errno (9 aka EBADF) is untranslated
230n/a w = OSError(9, 'foo', 'bar')
231n/a self.assertEqual(w.errno, 9)
232n/a self.assertEqual(w.winerror, None)
233n/a self.assertEqual(str(w), "[Errno 9] foo: 'bar'")
234n/a # ERROR_PATH_NOT_FOUND (win error 3) becomes ENOENT (2)
235n/a w = OSError(0, 'foo', 'bar', 3)
236n/a self.assertEqual(w.errno, 2)
237n/a self.assertEqual(w.winerror, 3)
238n/a self.assertEqual(w.strerror, 'foo')
239n/a self.assertEqual(w.filename, 'bar')
240n/a self.assertEqual(w.filename2, None)
241n/a self.assertEqual(str(w), "[WinError 3] foo: 'bar'")
242n/a # Unknown win error becomes EINVAL (22)
243n/a w = OSError(0, 'foo', None, 1001)
244n/a self.assertEqual(w.errno, 22)
245n/a self.assertEqual(w.winerror, 1001)
246n/a self.assertEqual(w.strerror, 'foo')
247n/a self.assertEqual(w.filename, None)
248n/a self.assertEqual(w.filename2, None)
249n/a self.assertEqual(str(w), "[WinError 1001] foo")
250n/a # Non-numeric "errno"
251n/a w = OSError('bar', 'foo')
252n/a self.assertEqual(w.errno, 'bar')
253n/a self.assertEqual(w.winerror, None)
254n/a self.assertEqual(w.strerror, 'foo')
255n/a self.assertEqual(w.filename, None)
256n/a self.assertEqual(w.filename2, None)
257n/a
258n/a @unittest.skipUnless(sys.platform == 'win32',
259n/a 'test specific to Windows')
260n/a def test_windows_message(self):
261n/a """Should fill in unknown error code in Windows error message"""
262n/a ctypes = import_module('ctypes')
263n/a # this error code has no message, Python formats it as hexadecimal
264n/a code = 3765269347
265n/a with self.assertRaisesRegex(OSError, 'Windows Error 0x%x' % code):
266n/a ctypes.pythonapi.PyErr_SetFromWindowsErr(code)
267n/a
268n/a def testAttributes(self):
269n/a # test that exception attributes are happy
270n/a
271n/a exceptionList = [
272n/a (BaseException, (), {'args' : ()}),
273n/a (BaseException, (1, ), {'args' : (1,)}),
274n/a (BaseException, ('foo',),
275n/a {'args' : ('foo',)}),
276n/a (BaseException, ('foo', 1),
277n/a {'args' : ('foo', 1)}),
278n/a (SystemExit, ('foo',),
279n/a {'args' : ('foo',), 'code' : 'foo'}),
280n/a (OSError, ('foo',),
281n/a {'args' : ('foo',), 'filename' : None, 'filename2' : None,
282n/a 'errno' : None, 'strerror' : None}),
283n/a (OSError, ('foo', 'bar'),
284n/a {'args' : ('foo', 'bar'),
285n/a 'filename' : None, 'filename2' : None,
286n/a 'errno' : 'foo', 'strerror' : 'bar'}),
287n/a (OSError, ('foo', 'bar', 'baz'),
288n/a {'args' : ('foo', 'bar'),
289n/a 'filename' : 'baz', 'filename2' : None,
290n/a 'errno' : 'foo', 'strerror' : 'bar'}),
291n/a (OSError, ('foo', 'bar', 'baz', None, 'quux'),
292n/a {'args' : ('foo', 'bar'), 'filename' : 'baz', 'filename2': 'quux'}),
293n/a (OSError, ('errnoStr', 'strErrorStr', 'filenameStr'),
294n/a {'args' : ('errnoStr', 'strErrorStr'),
295n/a 'strerror' : 'strErrorStr', 'errno' : 'errnoStr',
296n/a 'filename' : 'filenameStr'}),
297n/a (OSError, (1, 'strErrorStr', 'filenameStr'),
298n/a {'args' : (1, 'strErrorStr'), 'errno' : 1,
299n/a 'strerror' : 'strErrorStr',
300n/a 'filename' : 'filenameStr', 'filename2' : None}),
301n/a (SyntaxError, (), {'msg' : None, 'text' : None,
302n/a 'filename' : None, 'lineno' : None, 'offset' : None,
303n/a 'print_file_and_line' : None}),
304n/a (SyntaxError, ('msgStr',),
305n/a {'args' : ('msgStr',), 'text' : None,
306n/a 'print_file_and_line' : None, 'msg' : 'msgStr',
307n/a 'filename' : None, 'lineno' : None, 'offset' : None}),
308n/a (SyntaxError, ('msgStr', ('filenameStr', 'linenoStr', 'offsetStr',
309n/a 'textStr')),
310n/a {'offset' : 'offsetStr', 'text' : 'textStr',
311n/a 'args' : ('msgStr', ('filenameStr', 'linenoStr',
312n/a 'offsetStr', 'textStr')),
313n/a 'print_file_and_line' : None, 'msg' : 'msgStr',
314n/a 'filename' : 'filenameStr', 'lineno' : 'linenoStr'}),
315n/a (SyntaxError, ('msgStr', 'filenameStr', 'linenoStr', 'offsetStr',
316n/a 'textStr', 'print_file_and_lineStr'),
317n/a {'text' : None,
318n/a 'args' : ('msgStr', 'filenameStr', 'linenoStr', 'offsetStr',
319n/a 'textStr', 'print_file_and_lineStr'),
320n/a 'print_file_and_line' : None, 'msg' : 'msgStr',
321n/a 'filename' : None, 'lineno' : None, 'offset' : None}),
322n/a (UnicodeError, (), {'args' : (),}),
323n/a (UnicodeEncodeError, ('ascii', 'a', 0, 1,
324n/a 'ordinal not in range'),
325n/a {'args' : ('ascii', 'a', 0, 1,
326n/a 'ordinal not in range'),
327n/a 'encoding' : 'ascii', 'object' : 'a',
328n/a 'start' : 0, 'reason' : 'ordinal not in range'}),
329n/a (UnicodeDecodeError, ('ascii', bytearray(b'\xff'), 0, 1,
330n/a 'ordinal not in range'),
331n/a {'args' : ('ascii', bytearray(b'\xff'), 0, 1,
332n/a 'ordinal not in range'),
333n/a 'encoding' : 'ascii', 'object' : b'\xff',
334n/a 'start' : 0, 'reason' : 'ordinal not in range'}),
335n/a (UnicodeDecodeError, ('ascii', b'\xff', 0, 1,
336n/a 'ordinal not in range'),
337n/a {'args' : ('ascii', b'\xff', 0, 1,
338n/a 'ordinal not in range'),
339n/a 'encoding' : 'ascii', 'object' : b'\xff',
340n/a 'start' : 0, 'reason' : 'ordinal not in range'}),
341n/a (UnicodeTranslateError, ("\u3042", 0, 1, "ouch"),
342n/a {'args' : ('\u3042', 0, 1, 'ouch'),
343n/a 'object' : '\u3042', 'reason' : 'ouch',
344n/a 'start' : 0, 'end' : 1}),
345n/a (NaiveException, ('foo',),
346n/a {'args': ('foo',), 'x': 'foo'}),
347n/a (SlottedNaiveException, ('foo',),
348n/a {'args': ('foo',), 'x': 'foo'}),
349n/a ]
350n/a try:
351n/a # More tests are in test_WindowsError
352n/a exceptionList.append(
353n/a (WindowsError, (1, 'strErrorStr', 'filenameStr'),
354n/a {'args' : (1, 'strErrorStr'),
355n/a 'strerror' : 'strErrorStr', 'winerror' : None,
356n/a 'errno' : 1,
357n/a 'filename' : 'filenameStr', 'filename2' : None})
358n/a )
359n/a except NameError:
360n/a pass
361n/a
362n/a for exc, args, expected in exceptionList:
363n/a try:
364n/a e = exc(*args)
365n/a except:
366n/a print("\nexc=%r, args=%r" % (exc, args), file=sys.stderr)
367n/a raise
368n/a else:
369n/a # Verify module name
370n/a if not type(e).__name__.endswith('NaiveException'):
371n/a self.assertEqual(type(e).__module__, 'builtins')
372n/a # Verify no ref leaks in Exc_str()
373n/a s = str(e)
374n/a for checkArgName in expected:
375n/a value = getattr(e, checkArgName)
376n/a self.assertEqual(repr(value),
377n/a repr(expected[checkArgName]),
378n/a '%r.%s == %r, expected %r' % (
379n/a e, checkArgName,
380n/a value, expected[checkArgName]))
381n/a
382n/a # test for pickling support
383n/a for p in [pickle]:
384n/a for protocol in range(p.HIGHEST_PROTOCOL + 1):
385n/a s = p.dumps(e, protocol)
386n/a new = p.loads(s)
387n/a for checkArgName in expected:
388n/a got = repr(getattr(new, checkArgName))
389n/a want = repr(expected[checkArgName])
390n/a self.assertEqual(got, want,
391n/a 'pickled "%r", attribute "%s' %
392n/a (e, checkArgName))
393n/a
394n/a def testWithTraceback(self):
395n/a try:
396n/a raise IndexError(4)
397n/a except:
398n/a tb = sys.exc_info()[2]
399n/a
400n/a e = BaseException().with_traceback(tb)
401n/a self.assertIsInstance(e, BaseException)
402n/a self.assertEqual(e.__traceback__, tb)
403n/a
404n/a e = IndexError(5).with_traceback(tb)
405n/a self.assertIsInstance(e, IndexError)
406n/a self.assertEqual(e.__traceback__, tb)
407n/a
408n/a class MyException(Exception):
409n/a pass
410n/a
411n/a e = MyException().with_traceback(tb)
412n/a self.assertIsInstance(e, MyException)
413n/a self.assertEqual(e.__traceback__, tb)
414n/a
415n/a def testInvalidTraceback(self):
416n/a try:
417n/a Exception().__traceback__ = 5
418n/a except TypeError as e:
419n/a self.assertIn("__traceback__ must be a traceback", str(e))
420n/a else:
421n/a self.fail("No exception raised")
422n/a
423n/a def testInvalidAttrs(self):
424n/a self.assertRaises(TypeError, setattr, Exception(), '__cause__', 1)
425n/a self.assertRaises(TypeError, delattr, Exception(), '__cause__')
426n/a self.assertRaises(TypeError, setattr, Exception(), '__context__', 1)
427n/a self.assertRaises(TypeError, delattr, Exception(), '__context__')
428n/a
429n/a def testNoneClearsTracebackAttr(self):
430n/a try:
431n/a raise IndexError(4)
432n/a except:
433n/a tb = sys.exc_info()[2]
434n/a
435n/a e = Exception()
436n/a e.__traceback__ = tb
437n/a e.__traceback__ = None
438n/a self.assertEqual(e.__traceback__, None)
439n/a
440n/a def testChainingAttrs(self):
441n/a e = Exception()
442n/a self.assertIsNone(e.__context__)
443n/a self.assertIsNone(e.__cause__)
444n/a
445n/a e = TypeError()
446n/a self.assertIsNone(e.__context__)
447n/a self.assertIsNone(e.__cause__)
448n/a
449n/a class MyException(OSError):
450n/a pass
451n/a
452n/a e = MyException()
453n/a self.assertIsNone(e.__context__)
454n/a self.assertIsNone(e.__cause__)
455n/a
456n/a def testChainingDescriptors(self):
457n/a try:
458n/a raise Exception()
459n/a except Exception as exc:
460n/a e = exc
461n/a
462n/a self.assertIsNone(e.__context__)
463n/a self.assertIsNone(e.__cause__)
464n/a self.assertFalse(e.__suppress_context__)
465n/a
466n/a e.__context__ = NameError()
467n/a e.__cause__ = None
468n/a self.assertIsInstance(e.__context__, NameError)
469n/a self.assertIsNone(e.__cause__)
470n/a self.assertTrue(e.__suppress_context__)
471n/a e.__suppress_context__ = False
472n/a self.assertFalse(e.__suppress_context__)
473n/a
474n/a def testKeywordArgs(self):
475n/a # test that builtin exception don't take keyword args,
476n/a # but user-defined subclasses can if they want
477n/a self.assertRaises(TypeError, BaseException, a=1)
478n/a
479n/a class DerivedException(BaseException):
480n/a def __init__(self, fancy_arg):
481n/a BaseException.__init__(self)
482n/a self.fancy_arg = fancy_arg
483n/a
484n/a x = DerivedException(fancy_arg=42)
485n/a self.assertEqual(x.fancy_arg, 42)
486n/a
487n/a @no_tracing
488n/a def testInfiniteRecursion(self):
489n/a def f():
490n/a return f()
491n/a self.assertRaises(RecursionError, f)
492n/a
493n/a def g():
494n/a try:
495n/a return g()
496n/a except ValueError:
497n/a return -1
498n/a self.assertRaises(RecursionError, g)
499n/a
500n/a def test_str(self):
501n/a # Make sure both instances and classes have a str representation.
502n/a self.assertTrue(str(Exception))
503n/a self.assertTrue(str(Exception('a')))
504n/a self.assertTrue(str(Exception('a', 'b')))
505n/a
506n/a def testExceptionCleanupNames(self):
507n/a # Make sure the local variable bound to the exception instance by
508n/a # an "except" statement is only visible inside the except block.
509n/a try:
510n/a raise Exception()
511n/a except Exception as e:
512n/a self.assertTrue(e)
513n/a del e
514n/a self.assertNotIn('e', locals())
515n/a
516n/a def testExceptionCleanupState(self):
517n/a # Make sure exception state is cleaned up as soon as the except
518n/a # block is left. See #2507
519n/a
520n/a class MyException(Exception):
521n/a def __init__(self, obj):
522n/a self.obj = obj
523n/a class MyObj:
524n/a pass
525n/a
526n/a def inner_raising_func():
527n/a # Create some references in exception value and traceback
528n/a local_ref = obj
529n/a raise MyException(obj)
530n/a
531n/a # Qualified "except" with "as"
532n/a obj = MyObj()
533n/a wr = weakref.ref(obj)
534n/a try:
535n/a inner_raising_func()
536n/a except MyException as e:
537n/a pass
538n/a obj = None
539n/a obj = wr()
540n/a self.assertTrue(obj is None, "%s" % obj)
541n/a
542n/a # Qualified "except" without "as"
543n/a obj = MyObj()
544n/a wr = weakref.ref(obj)
545n/a try:
546n/a inner_raising_func()
547n/a except MyException:
548n/a pass
549n/a obj = None
550n/a obj = wr()
551n/a self.assertTrue(obj is None, "%s" % obj)
552n/a
553n/a # Bare "except"
554n/a obj = MyObj()
555n/a wr = weakref.ref(obj)
556n/a try:
557n/a inner_raising_func()
558n/a except:
559n/a pass
560n/a obj = None
561n/a obj = wr()
562n/a self.assertTrue(obj is None, "%s" % obj)
563n/a
564n/a # "except" with premature block leave
565n/a obj = MyObj()
566n/a wr = weakref.ref(obj)
567n/a for i in [0]:
568n/a try:
569n/a inner_raising_func()
570n/a except:
571n/a break
572n/a obj = None
573n/a obj = wr()
574n/a self.assertTrue(obj is None, "%s" % obj)
575n/a
576n/a # "except" block raising another exception
577n/a obj = MyObj()
578n/a wr = weakref.ref(obj)
579n/a try:
580n/a try:
581n/a inner_raising_func()
582n/a except:
583n/a raise KeyError
584n/a except KeyError as e:
585n/a # We want to test that the except block above got rid of
586n/a # the exception raised in inner_raising_func(), but it
587n/a # also ends up in the __context__ of the KeyError, so we
588n/a # must clear the latter manually for our test to succeed.
589n/a e.__context__ = None
590n/a obj = None
591n/a obj = wr()
592n/a # guarantee no ref cycles on CPython (don't gc_collect)
593n/a if check_impl_detail(cpython=False):
594n/a gc_collect()
595n/a self.assertTrue(obj is None, "%s" % obj)
596n/a
597n/a # Some complicated construct
598n/a obj = MyObj()
599n/a wr = weakref.ref(obj)
600n/a try:
601n/a inner_raising_func()
602n/a except MyException:
603n/a try:
604n/a try:
605n/a raise
606n/a finally:
607n/a raise
608n/a except MyException:
609n/a pass
610n/a obj = None
611n/a if check_impl_detail(cpython=False):
612n/a gc_collect()
613n/a obj = wr()
614n/a self.assertTrue(obj is None, "%s" % obj)
615n/a
616n/a # Inside an exception-silencing "with" block
617n/a class Context:
618n/a def __enter__(self):
619n/a return self
620n/a def __exit__ (self, exc_type, exc_value, exc_tb):
621n/a return True
622n/a obj = MyObj()
623n/a wr = weakref.ref(obj)
624n/a with Context():
625n/a inner_raising_func()
626n/a obj = None
627n/a if check_impl_detail(cpython=False):
628n/a gc_collect()
629n/a obj = wr()
630n/a self.assertTrue(obj is None, "%s" % obj)
631n/a
632n/a def test_exception_target_in_nested_scope(self):
633n/a # issue 4617: This used to raise a SyntaxError
634n/a # "can not delete variable 'e' referenced in nested scope"
635n/a def print_error():
636n/a e
637n/a try:
638n/a something
639n/a except Exception as e:
640n/a print_error()
641n/a # implicit "del e" here
642n/a
643n/a def test_generator_leaking(self):
644n/a # Test that generator exception state doesn't leak into the calling
645n/a # frame
646n/a def yield_raise():
647n/a try:
648n/a raise KeyError("caught")
649n/a except KeyError:
650n/a yield sys.exc_info()[0]
651n/a yield sys.exc_info()[0]
652n/a yield sys.exc_info()[0]
653n/a g = yield_raise()
654n/a self.assertEqual(next(g), KeyError)
655n/a self.assertEqual(sys.exc_info()[0], None)
656n/a self.assertEqual(next(g), KeyError)
657n/a self.assertEqual(sys.exc_info()[0], None)
658n/a self.assertEqual(next(g), None)
659n/a
660n/a # Same test, but inside an exception handler
661n/a try:
662n/a raise TypeError("foo")
663n/a except TypeError:
664n/a g = yield_raise()
665n/a self.assertEqual(next(g), KeyError)
666n/a self.assertEqual(sys.exc_info()[0], TypeError)
667n/a self.assertEqual(next(g), KeyError)
668n/a self.assertEqual(sys.exc_info()[0], TypeError)
669n/a self.assertEqual(next(g), TypeError)
670n/a del g
671n/a self.assertEqual(sys.exc_info()[0], TypeError)
672n/a
673n/a def test_generator_leaking2(self):
674n/a # See issue 12475.
675n/a def g():
676n/a yield
677n/a try:
678n/a raise RuntimeError
679n/a except RuntimeError:
680n/a it = g()
681n/a next(it)
682n/a try:
683n/a next(it)
684n/a except StopIteration:
685n/a pass
686n/a self.assertEqual(sys.exc_info(), (None, None, None))
687n/a
688n/a def test_generator_leaking3(self):
689n/a # See issue #23353. When gen.throw() is called, the caller's
690n/a # exception state should be save and restored.
691n/a def g():
692n/a try:
693n/a yield
694n/a except ZeroDivisionError:
695n/a yield sys.exc_info()[1]
696n/a it = g()
697n/a next(it)
698n/a try:
699n/a 1/0
700n/a except ZeroDivisionError as e:
701n/a self.assertIs(sys.exc_info()[1], e)
702n/a gen_exc = it.throw(e)
703n/a self.assertIs(sys.exc_info()[1], e)
704n/a self.assertIs(gen_exc, e)
705n/a self.assertEqual(sys.exc_info(), (None, None, None))
706n/a
707n/a def test_generator_leaking4(self):
708n/a # See issue #23353. When an exception is raised by a generator,
709n/a # the caller's exception state should still be restored.
710n/a def g():
711n/a try:
712n/a 1/0
713n/a except ZeroDivisionError:
714n/a yield sys.exc_info()[0]
715n/a raise
716n/a it = g()
717n/a try:
718n/a raise TypeError
719n/a except TypeError:
720n/a # The caller's exception state (TypeError) is temporarily
721n/a # saved in the generator.
722n/a tp = next(it)
723n/a self.assertIs(tp, ZeroDivisionError)
724n/a try:
725n/a next(it)
726n/a # We can't check it immediately, but while next() returns
727n/a # with an exception, it shouldn't have restored the old
728n/a # exception state (TypeError).
729n/a except ZeroDivisionError as e:
730n/a self.assertIs(sys.exc_info()[1], e)
731n/a # We used to find TypeError here.
732n/a self.assertEqual(sys.exc_info(), (None, None, None))
733n/a
734n/a def test_generator_doesnt_retain_old_exc(self):
735n/a def g():
736n/a self.assertIsInstance(sys.exc_info()[1], RuntimeError)
737n/a yield
738n/a self.assertEqual(sys.exc_info(), (None, None, None))
739n/a it = g()
740n/a try:
741n/a raise RuntimeError
742n/a except RuntimeError:
743n/a next(it)
744n/a self.assertRaises(StopIteration, next, it)
745n/a
746n/a def test_generator_finalizing_and_exc_info(self):
747n/a # See #7173
748n/a def simple_gen():
749n/a yield 1
750n/a def run_gen():
751n/a gen = simple_gen()
752n/a try:
753n/a raise RuntimeError
754n/a except RuntimeError:
755n/a return next(gen)
756n/a run_gen()
757n/a gc_collect()
758n/a self.assertEqual(sys.exc_info(), (None, None, None))
759n/a
760n/a def _check_generator_cleanup_exc_state(self, testfunc):
761n/a # Issue #12791: exception state is cleaned up as soon as a generator
762n/a # is closed (reference cycles are broken).
763n/a class MyException(Exception):
764n/a def __init__(self, obj):
765n/a self.obj = obj
766n/a class MyObj:
767n/a pass
768n/a
769n/a def raising_gen():
770n/a try:
771n/a raise MyException(obj)
772n/a except MyException:
773n/a yield
774n/a
775n/a obj = MyObj()
776n/a wr = weakref.ref(obj)
777n/a g = raising_gen()
778n/a next(g)
779n/a testfunc(g)
780n/a g = obj = None
781n/a obj = wr()
782n/a self.assertIs(obj, None)
783n/a
784n/a def test_generator_throw_cleanup_exc_state(self):
785n/a def do_throw(g):
786n/a try:
787n/a g.throw(RuntimeError())
788n/a except RuntimeError:
789n/a pass
790n/a self._check_generator_cleanup_exc_state(do_throw)
791n/a
792n/a def test_generator_close_cleanup_exc_state(self):
793n/a def do_close(g):
794n/a g.close()
795n/a self._check_generator_cleanup_exc_state(do_close)
796n/a
797n/a def test_generator_del_cleanup_exc_state(self):
798n/a def do_del(g):
799n/a g = None
800n/a self._check_generator_cleanup_exc_state(do_del)
801n/a
802n/a def test_generator_next_cleanup_exc_state(self):
803n/a def do_next(g):
804n/a try:
805n/a next(g)
806n/a except StopIteration:
807n/a pass
808n/a else:
809n/a self.fail("should have raised StopIteration")
810n/a self._check_generator_cleanup_exc_state(do_next)
811n/a
812n/a def test_generator_send_cleanup_exc_state(self):
813n/a def do_send(g):
814n/a try:
815n/a g.send(None)
816n/a except StopIteration:
817n/a pass
818n/a else:
819n/a self.fail("should have raised StopIteration")
820n/a self._check_generator_cleanup_exc_state(do_send)
821n/a
822n/a def test_3114(self):
823n/a # Bug #3114: in its destructor, MyObject retrieves a pointer to
824n/a # obsolete and/or deallocated objects.
825n/a class MyObject:
826n/a def __del__(self):
827n/a nonlocal e
828n/a e = sys.exc_info()
829n/a e = ()
830n/a try:
831n/a raise Exception(MyObject())
832n/a except:
833n/a pass
834n/a self.assertEqual(e, (None, None, None))
835n/a
836n/a def test_unicode_change_attributes(self):
837n/a # See issue 7309. This was a crasher.
838n/a
839n/a u = UnicodeEncodeError('baz', 'xxxxx', 1, 5, 'foo')
840n/a self.assertEqual(str(u), "'baz' codec can't encode characters in position 1-4: foo")
841n/a u.end = 2
842n/a self.assertEqual(str(u), "'baz' codec can't encode character '\\x78' in position 1: foo")
843n/a u.end = 5
844n/a u.reason = 0x345345345345345345
845n/a self.assertEqual(str(u), "'baz' codec can't encode characters in position 1-4: 965230951443685724997")
846n/a u.encoding = 4000
847n/a self.assertEqual(str(u), "'4000' codec can't encode characters in position 1-4: 965230951443685724997")
848n/a u.start = 1000
849n/a self.assertEqual(str(u), "'4000' codec can't encode characters in position 1000-4: 965230951443685724997")
850n/a
851n/a u = UnicodeDecodeError('baz', b'xxxxx', 1, 5, 'foo')
852n/a self.assertEqual(str(u), "'baz' codec can't decode bytes in position 1-4: foo")
853n/a u.end = 2
854n/a self.assertEqual(str(u), "'baz' codec can't decode byte 0x78 in position 1: foo")
855n/a u.end = 5
856n/a u.reason = 0x345345345345345345
857n/a self.assertEqual(str(u), "'baz' codec can't decode bytes in position 1-4: 965230951443685724997")
858n/a u.encoding = 4000
859n/a self.assertEqual(str(u), "'4000' codec can't decode bytes in position 1-4: 965230951443685724997")
860n/a u.start = 1000
861n/a self.assertEqual(str(u), "'4000' codec can't decode bytes in position 1000-4: 965230951443685724997")
862n/a
863n/a u = UnicodeTranslateError('xxxx', 1, 5, 'foo')
864n/a self.assertEqual(str(u), "can't translate characters in position 1-4: foo")
865n/a u.end = 2
866n/a self.assertEqual(str(u), "can't translate character '\\x78' in position 1: foo")
867n/a u.end = 5
868n/a u.reason = 0x345345345345345345
869n/a self.assertEqual(str(u), "can't translate characters in position 1-4: 965230951443685724997")
870n/a u.start = 1000
871n/a self.assertEqual(str(u), "can't translate characters in position 1000-4: 965230951443685724997")
872n/a
873n/a def test_unicode_errors_no_object(self):
874n/a # See issue #21134.
875n/a klasses = UnicodeEncodeError, UnicodeDecodeError, UnicodeTranslateError
876n/a for klass in klasses:
877n/a self.assertEqual(str(klass.__new__(klass)), "")
878n/a
879n/a @no_tracing
880n/a def test_badisinstance(self):
881n/a # Bug #2542: if issubclass(e, MyException) raises an exception,
882n/a # it should be ignored
883n/a class Meta(type):
884n/a def __subclasscheck__(cls, subclass):
885n/a raise ValueError()
886n/a class MyException(Exception, metaclass=Meta):
887n/a pass
888n/a
889n/a with captured_stderr() as stderr:
890n/a try:
891n/a raise KeyError()
892n/a except MyException as e:
893n/a self.fail("exception should not be a MyException")
894n/a except KeyError:
895n/a pass
896n/a except:
897n/a self.fail("Should have raised KeyError")
898n/a else:
899n/a self.fail("Should have raised KeyError")
900n/a
901n/a def g():
902n/a try:
903n/a return g()
904n/a except RecursionError:
905n/a return sys.exc_info()
906n/a e, v, tb = g()
907n/a self.assertTrue(isinstance(v, RecursionError), type(v))
908n/a self.assertIn("maximum recursion depth exceeded", str(v))
909n/a
910n/a
911n/a @cpython_only
912n/a def test_MemoryError(self):
913n/a # PyErr_NoMemory always raises the same exception instance.
914n/a # Check that the traceback is not doubled.
915n/a import traceback
916n/a from _testcapi import raise_memoryerror
917n/a def raiseMemError():
918n/a try:
919n/a raise_memoryerror()
920n/a except MemoryError as e:
921n/a tb = e.__traceback__
922n/a else:
923n/a self.fail("Should have raises a MemoryError")
924n/a return traceback.format_tb(tb)
925n/a
926n/a tb1 = raiseMemError()
927n/a tb2 = raiseMemError()
928n/a self.assertEqual(tb1, tb2)
929n/a
930n/a @cpython_only
931n/a def test_exception_with_doc(self):
932n/a import _testcapi
933n/a doc2 = "This is a test docstring."
934n/a doc4 = "This is another test docstring."
935n/a
936n/a self.assertRaises(SystemError, _testcapi.make_exception_with_doc,
937n/a "error1")
938n/a
939n/a # test basic usage of PyErr_NewException
940n/a error1 = _testcapi.make_exception_with_doc("_testcapi.error1")
941n/a self.assertIs(type(error1), type)
942n/a self.assertTrue(issubclass(error1, Exception))
943n/a self.assertIsNone(error1.__doc__)
944n/a
945n/a # test with given docstring
946n/a error2 = _testcapi.make_exception_with_doc("_testcapi.error2", doc2)
947n/a self.assertEqual(error2.__doc__, doc2)
948n/a
949n/a # test with explicit base (without docstring)
950n/a error3 = _testcapi.make_exception_with_doc("_testcapi.error3",
951n/a base=error2)
952n/a self.assertTrue(issubclass(error3, error2))
953n/a
954n/a # test with explicit base tuple
955n/a class C(object):
956n/a pass
957n/a error4 = _testcapi.make_exception_with_doc("_testcapi.error4", doc4,
958n/a (error3, C))
959n/a self.assertTrue(issubclass(error4, error3))
960n/a self.assertTrue(issubclass(error4, C))
961n/a self.assertEqual(error4.__doc__, doc4)
962n/a
963n/a # test with explicit dictionary
964n/a error5 = _testcapi.make_exception_with_doc("_testcapi.error5", "",
965n/a error4, {'a': 1})
966n/a self.assertTrue(issubclass(error5, error4))
967n/a self.assertEqual(error5.a, 1)
968n/a self.assertEqual(error5.__doc__, "")
969n/a
970n/a @cpython_only
971n/a def test_memory_error_cleanup(self):
972n/a # Issue #5437: preallocated MemoryError instances should not keep
973n/a # traceback objects alive.
974n/a from _testcapi import raise_memoryerror
975n/a class C:
976n/a pass
977n/a wr = None
978n/a def inner():
979n/a nonlocal wr
980n/a c = C()
981n/a wr = weakref.ref(c)
982n/a raise_memoryerror()
983n/a # We cannot use assertRaises since it manually deletes the traceback
984n/a try:
985n/a inner()
986n/a except MemoryError as e:
987n/a self.assertNotEqual(wr(), None)
988n/a else:
989n/a self.fail("MemoryError not raised")
990n/a self.assertEqual(wr(), None)
991n/a
992n/a @no_tracing
993n/a def test_recursion_error_cleanup(self):
994n/a # Same test as above, but with "recursion exceeded" errors
995n/a class C:
996n/a pass
997n/a wr = None
998n/a def inner():
999n/a nonlocal wr
1000n/a c = C()
1001n/a wr = weakref.ref(c)
1002n/a inner()
1003n/a # We cannot use assertRaises since it manually deletes the traceback
1004n/a try:
1005n/a inner()
1006n/a except RecursionError as e:
1007n/a self.assertNotEqual(wr(), None)
1008n/a else:
1009n/a self.fail("RecursionError not raised")
1010n/a self.assertEqual(wr(), None)
1011n/a
1012n/a def test_errno_ENOTDIR(self):
1013n/a # Issue #12802: "not a directory" errors are ENOTDIR even on Windows
1014n/a with self.assertRaises(OSError) as cm:
1015n/a os.listdir(__file__)
1016n/a self.assertEqual(cm.exception.errno, errno.ENOTDIR, cm.exception)
1017n/a
1018n/a def test_unraisable(self):
1019n/a # Issue #22836: PyErr_WriteUnraisable() should give sensible reports
1020n/a class BrokenDel:
1021n/a def __del__(self):
1022n/a exc = ValueError("del is broken")
1023n/a # The following line is included in the traceback report:
1024n/a raise exc
1025n/a
1026n/a class BrokenExceptionDel:
1027n/a def __del__(self):
1028n/a exc = BrokenStrException()
1029n/a # The following line is included in the traceback report:
1030n/a raise exc
1031n/a
1032n/a for test_class in (BrokenDel, BrokenExceptionDel):
1033n/a with self.subTest(test_class):
1034n/a obj = test_class()
1035n/a with captured_stderr() as stderr:
1036n/a del obj
1037n/a report = stderr.getvalue()
1038n/a self.assertIn("Exception ignored", report)
1039n/a self.assertIn(test_class.__del__.__qualname__, report)
1040n/a self.assertIn("test_exceptions.py", report)
1041n/a self.assertIn("raise exc", report)
1042n/a if test_class is BrokenExceptionDel:
1043n/a self.assertIn("BrokenStrException", report)
1044n/a self.assertIn("<exception str() failed>", report)
1045n/a else:
1046n/a self.assertIn("ValueError", report)
1047n/a self.assertIn("del is broken", report)
1048n/a self.assertTrue(report.endswith("\n"))
1049n/a
1050n/a def test_unhandled(self):
1051n/a # Check for sensible reporting of unhandled exceptions
1052n/a for exc_type in (ValueError, BrokenStrException):
1053n/a with self.subTest(exc_type):
1054n/a try:
1055n/a exc = exc_type("test message")
1056n/a # The following line is included in the traceback report:
1057n/a raise exc
1058n/a except exc_type:
1059n/a with captured_stderr() as stderr:
1060n/a sys.__excepthook__(*sys.exc_info())
1061n/a report = stderr.getvalue()
1062n/a self.assertIn("test_exceptions.py", report)
1063n/a self.assertIn("raise exc", report)
1064n/a self.assertIn(exc_type.__name__, report)
1065n/a if exc_type is BrokenStrException:
1066n/a self.assertIn("<exception str() failed>", report)
1067n/a else:
1068n/a self.assertIn("test message", report)
1069n/a self.assertTrue(report.endswith("\n"))
1070n/a
1071n/a
1072n/aclass ImportErrorTests(unittest.TestCase):
1073n/a
1074n/a def test_attributes(self):
1075n/a # Setting 'name' and 'path' should not be a problem.
1076n/a exc = ImportError('test')
1077n/a self.assertIsNone(exc.name)
1078n/a self.assertIsNone(exc.path)
1079n/a
1080n/a exc = ImportError('test', name='somemodule')
1081n/a self.assertEqual(exc.name, 'somemodule')
1082n/a self.assertIsNone(exc.path)
1083n/a
1084n/a exc = ImportError('test', path='somepath')
1085n/a self.assertEqual(exc.path, 'somepath')
1086n/a self.assertIsNone(exc.name)
1087n/a
1088n/a exc = ImportError('test', path='somepath', name='somename')
1089n/a self.assertEqual(exc.name, 'somename')
1090n/a self.assertEqual(exc.path, 'somepath')
1091n/a
1092n/a msg = "'invalid' is an invalid keyword argument for this function"
1093n/a with self.assertRaisesRegex(TypeError, msg):
1094n/a ImportError('test', invalid='keyword')
1095n/a
1096n/a with self.assertRaisesRegex(TypeError, msg):
1097n/a ImportError('test', name='name', invalid='keyword')
1098n/a
1099n/a with self.assertRaisesRegex(TypeError, msg):
1100n/a ImportError('test', path='path', invalid='keyword')
1101n/a
1102n/a with self.assertRaisesRegex(TypeError, msg):
1103n/a ImportError(invalid='keyword')
1104n/a
1105n/a with self.assertRaisesRegex(TypeError, msg):
1106n/a ImportError('test', invalid='keyword', another=True)
1107n/a
1108n/a def test_reset_attributes(self):
1109n/a exc = ImportError('test', name='name', path='path')
1110n/a self.assertEqual(exc.args, ('test',))
1111n/a self.assertEqual(exc.msg, 'test')
1112n/a self.assertEqual(exc.name, 'name')
1113n/a self.assertEqual(exc.path, 'path')
1114n/a
1115n/a # Reset not specified attributes
1116n/a exc.__init__()
1117n/a self.assertEqual(exc.args, ())
1118n/a self.assertEqual(exc.msg, None)
1119n/a self.assertEqual(exc.name, None)
1120n/a self.assertEqual(exc.path, None)
1121n/a
1122n/a def test_non_str_argument(self):
1123n/a # Issue #15778
1124n/a with check_warnings(('', BytesWarning), quiet=True):
1125n/a arg = b'abc'
1126n/a exc = ImportError(arg)
1127n/a self.assertEqual(str(arg), str(exc))
1128n/a
1129n/a
1130n/aif __name__ == '__main__':
1131n/a unittest.main()