Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(247495)

Delta Between Two Patch Sets: Lib/test/test_traceback.py

Issue 16510: Using appropriate checks in tests
Left Patch Set: Created 5 years, 11 months ago
Right Patch Set: Created 5 years, 6 months ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
Left: Side by side diff | Download
Right: Side by side diff | Download
« no previous file with change/comment | « Lib/test/test_time.py ('k') | Lib/test/test_trace.py » ('j') | no next file with change/comment »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
LEFTRIGHT
1 """Test cases for traceback module""" 1 """Test cases for traceback module"""
2 2
3 from _testcapi import traceback_print, exception_print
4 from io import StringIO 3 from io import StringIO
5 import sys 4 import sys
6 import unittest 5 import unittest
7 import re 6 import re
8 from test.support import run_unittest, Error, captured_output 7 from test.support import run_unittest, Error, captured_output
9 from test.support import TESTFN, unlink 8 from test.support import TESTFN, unlink, cpython_only
10 9
11 import traceback 10 import traceback
12 11
13 12
14 class SyntaxTracebackCases(unittest.TestCase): 13 class SyntaxTracebackCases(unittest.TestCase):
15 # For now, a very minimal set of tests. I want to be sure that 14 # For now, a very minimal set of tests. I want to be sure that
16 # formatting of SyntaxErrors works based on changes for 2.1. 15 # formatting of SyntaxErrors works based on changes for 2.1.
17 16
18 def get_exception_format(self, func, exc): 17 def get_exception_format(self, func, exc):
19 try: 18 try:
20 func() 19 func()
21 except exc as value: 20 except exc as value:
22 return traceback.format_exception_only(exc, value) 21 return traceback.format_exception_only(exc, value)
23 else: 22 else:
24 raise ValueError("call did not raise exception") 23 raise ValueError("call did not raise exception")
25 24
26 def syntax_error_with_caret(self): 25 def syntax_error_with_caret(self):
27 compile("def fact(x):\n\treturn x!\n", "?", "exec") 26 compile("def fact(x):\n\treturn x!\n", "?", "exec")
28 27
29 def syntax_error_with_caret_2(self): 28 def syntax_error_with_caret_2(self):
30 compile("1 +\n", "?", "exec") 29 compile("1 +\n", "?", "exec")
31 30
32 def syntax_error_bad_indentation(self): 31 def syntax_error_bad_indentation(self):
33 compile("def spam():\n print(1)\n print(2)", "?", "exec") 32 compile("def spam():\n print(1)\n print(2)", "?", "exec")
33
34 def syntax_error_with_caret_non_ascii(self):
35 compile('Python = "\u1e54\xfd\u0163\u0125\xf2\xf1" +', "?", "exec")
36
37 def syntax_error_bad_indentation2(self):
38 compile(" print(2)", "?", "exec")
34 39
35 def test_caret(self): 40 def test_caret(self):
36 err = self.get_exception_format(self.syntax_error_with_caret, 41 err = self.get_exception_format(self.syntax_error_with_caret,
37 SyntaxError) 42 SyntaxError)
38 self.assertEqual(len(err), 4) 43 self.assertEqual(len(err), 4)
39 self.assertEqual(err[1].strip(), "return x!") 44 self.assertEqual(err[1].strip(), "return x!")
40 self.assertIn("^", err[2]) # third line has caret 45 self.assertIn("^", err[2]) # third line has caret
41 self.assertEqual(err[1].find("!"), err[2].find("^")) # in the right plac e 46 self.assertEqual(err[1].find("!"), err[2].find("^")) # in the right plac e
42 47
43 err = self.get_exception_format(self.syntax_error_with_caret_2, 48 err = self.get_exception_format(self.syntax_error_with_caret_2,
44 SyntaxError) 49 SyntaxError)
45 self.assertIn("^", err[2]) # third line has caret 50 self.assertIn("^", err[2]) # third line has caret
46 self.assertEqual(err[2].count('\n'), 1) # and no additional newline 51 self.assertEqual(err[2].count('\n'), 1) # and no additional newline
47 self.assertEqual(err[1].find("+"), err[2].find("^")) # in the right plac e 52 self.assertEqual(err[1].find("+"), err[2].find("^")) # in the right pla ce
53
54 err = self.get_exception_format(self.syntax_error_with_caret_non_ascii,
55 SyntaxError)
56 self.assertIn("^", err[2]) # third line has caret
57 self.assertEqual(err[2].count('\n'), 1) # and no additional newline
58 self.assertEqual(err[1].find("+"), err[2].find("^")) # in the right pla ce
48 59
49 def test_nocaret(self): 60 def test_nocaret(self):
50 exc = SyntaxError("error", ("x.py", 23, None, "bad syntax")) 61 exc = SyntaxError("error", ("x.py", 23, None, "bad syntax"))
51 err = traceback.format_exception_only(SyntaxError, exc) 62 err = traceback.format_exception_only(SyntaxError, exc)
52 self.assertEqual(len(err), 3) 63 self.assertEqual(len(err), 3)
53 self.assertEqual(err[1].strip(), "bad syntax") 64 self.assertEqual(err[1].strip(), "bad syntax")
54 65
55 def test_bad_indentation(self): 66 def test_bad_indentation(self):
56 err = self.get_exception_format(self.syntax_error_bad_indentation, 67 err = self.get_exception_format(self.syntax_error_bad_indentation,
57 IndentationError) 68 IndentationError)
58 self.assertEqual(len(err), 4) 69 self.assertEqual(len(err), 4)
59 self.assertEqual(err[1].strip(), "print(2)") 70 self.assertEqual(err[1].strip(), "print(2)")
60 self.assertIn("^", err[2]) 71 self.assertIn("^", err[2])
61 self.assertEqual(err[1].find(")"), err[2].find("^")) 72 self.assertEqual(err[1].find(")"), err[2].find("^"))
73
74 err = self.get_exception_format(self.syntax_error_bad_indentation2,
75 IndentationError)
76 self.assertEqual(len(err), 4)
77 self.assertEqual(err[1].strip(), "print(2)")
78 self.assertIn("^", err[2])
79 self.assertEqual(err[1].find("p"), err[2].find("^"))
62 80
63 def test_base_exception(self): 81 def test_base_exception(self):
64 # Test that exceptions derived from BaseException are formatted right 82 # Test that exceptions derived from BaseException are formatted right
65 e = KeyboardInterrupt() 83 e = KeyboardInterrupt()
66 lst = traceback.format_exception_only(e.__class__, e) 84 lst = traceback.format_exception_only(e.__class__, e)
67 self.assertEqual(lst, ['KeyboardInterrupt\n']) 85 self.assertEqual(lst, ['KeyboardInterrupt\n'])
68 86
69 def test_format_exception_only_bad__str__(self): 87 def test_format_exception_only_bad__str__(self):
70 class X(Exception): 88 class X(Exception):
71 def __str__(self): 89 def __str__(self):
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
139 if charset == "ascii": 157 if charset == "ascii":
140 text = "foo" 158 text = "foo"
141 elif charset == "GBK": 159 elif charset == "GBK":
142 text = "\u4E02\u5100" 160 text = "\u4E02\u5100"
143 else: 161 else:
144 text = "h\xe9 ho" 162 text = "h\xe9 ho"
145 do_test("# coding: {0}\n".format(charset), 163 do_test("# coding: {0}\n".format(charset),
146 text, charset, 4) 164 text, charset, 4)
147 do_test("#!shebang\n# coding: {0}\n".format(charset), 165 do_test("#!shebang\n# coding: {0}\n".format(charset),
148 text, charset, 5) 166 text, charset, 5)
167 do_test(" \t\f\n# coding: {0}\n".format(charset),
168 text, charset, 5)
169 # Issue #18960: coding spec should has no effect
170 do_test("0\n# coding: GBK\n", "h\xe9 ho", 'utf-8', 5)
149 171
150 172
151 class TracebackFormatTests(unittest.TestCase): 173 class TracebackFormatTests(unittest.TestCase):
152 174
153 def test_traceback_format(self): 175 def some_exception(self):
154 try: 176 raise KeyError('blah')
155 raise KeyError('blah') 177
178 @cpython_only
179 def check_traceback_format(self, cleanup_func=None):
180 from _testcapi import traceback_print
181 try:
182 self.some_exception()
156 except KeyError: 183 except KeyError:
157 type_, value, tb = sys.exc_info() 184 type_, value, tb = sys.exc_info()
185 if cleanup_func is not None:
186 # Clear the inner frames, not this one
187 cleanup_func(tb.tb_next)
158 traceback_fmt = 'Traceback (most recent call last):\n' + \ 188 traceback_fmt = 'Traceback (most recent call last):\n' + \
159 ''.join(traceback.format_tb(tb)) 189 ''.join(traceback.format_tb(tb))
160 file_ = StringIO() 190 file_ = StringIO()
161 traceback_print(tb, file_) 191 traceback_print(tb, file_)
162 python_fmt = file_.getvalue() 192 python_fmt = file_.getvalue()
193 # Call all _tb and _exc functions
194 with captured_output("stderr") as tbstderr:
195 traceback.print_tb(tb)
196 tbfile = StringIO()
197 traceback.print_tb(tb, file=tbfile)
198 with captured_output("stderr") as excstderr:
199 traceback.print_exc()
200 excfmt = traceback.format_exc()
201 excfile = StringIO()
202 traceback.print_exc(file=excfile)
163 else: 203 else:
164 raise Error("unable to create test traceback string") 204 raise Error("unable to create test traceback string")
165 205
166 # Make sure that Python and the traceback module format the same thing 206 # Make sure that Python and the traceback module format the same thing
167 self.assertEqual(traceback_fmt, python_fmt) 207 self.assertEqual(traceback_fmt, python_fmt)
208 # Now verify the _tb func output
209 self.assertEqual(tbstderr.getvalue(), tbfile.getvalue())
210 # Now verify the _exc func output
211 self.assertEqual(excstderr.getvalue(), excfile.getvalue())
212 self.assertEqual(excfmt, excfile.getvalue())
168 213
169 # Make sure that the traceback is properly indented. 214 # Make sure that the traceback is properly indented.
170 tb_lines = python_fmt.splitlines() 215 tb_lines = python_fmt.splitlines()
171 self.assertEqual(len(tb_lines), 3) 216 self.assertEqual(len(tb_lines), 5)
172 banner, location, source_line = tb_lines 217 banner = tb_lines[0]
218 location, source_line = tb_lines[-2:]
173 self.assertTrue(banner.startswith('Traceback')) 219 self.assertTrue(banner.startswith('Traceback'))
174 self.assertTrue(location.startswith(' File')) 220 self.assertTrue(location.startswith(' File'))
175 self.assertTrue(source_line.startswith(' raise')) 221 self.assertTrue(source_line.startswith(' raise'))
222
223 def test_traceback_format(self):
224 self.check_traceback_format()
225
226 def test_traceback_format_with_cleared_frames(self):
227 # Check that traceback formatting also works with a clear()ed frame
228 def cleanup_tb(tb):
229 tb.tb_frame.clear()
230 self.check_traceback_format(cleanup_tb)
231
232 def test_stack_format(self):
233 # Verify _stack functions. Note we have to use _getframe(1) to
234 # compare them without this frame appearing in the output
235 with captured_output("stderr") as ststderr:
236 traceback.print_stack(sys._getframe(1))
237 stfile = StringIO()
238 traceback.print_stack(sys._getframe(1), file=stfile)
239 self.assertEqual(ststderr.getvalue(), stfile.getvalue())
240
241 stfmt = traceback.format_stack(sys._getframe(1))
242
243 self.assertEqual(ststderr.getvalue(), "".join(stfmt))
176 244
177 245
178 cause_message = ( 246 cause_message = (
179 "\nThe above exception was the direct cause " 247 "\nThe above exception was the direct cause "
180 "of the following exception:\n\n") 248 "of the following exception:\n\n")
181 249
182 context_message = ( 250 context_message = (
183 "\nDuring handling of the above exception, " 251 "\nDuring handling of the above exception, "
184 "another exception occurred:\n\n") 252 "another exception occurred:\n\n")
185 253
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after
330 traceback.print_exception(type(e), e, e.__traceback__) 398 traceback.print_exception(type(e), e, e.__traceback__)
331 self.assertEqual(sio.getvalue(), s) 399 self.assertEqual(sio.getvalue(), s)
332 return s 400 return s
333 401
334 402
335 class CExcReportingTests(BaseExceptionReportingTests, unittest.TestCase): 403 class CExcReportingTests(BaseExceptionReportingTests, unittest.TestCase):
336 # 404 #
337 # This checks built-in reporting by the interpreter. 405 # This checks built-in reporting by the interpreter.
338 # 406 #
339 407
408 @cpython_only
340 def get_report(self, e): 409 def get_report(self, e):
410 from _testcapi import exception_print
341 e = self.get_exception(e) 411 e = self.get_exception(e)
342 with captured_output("stderr") as s: 412 with captured_output("stderr") as s:
343 exception_print(e) 413 exception_print(e)
344 return s.getvalue() 414 return s.getvalue()
345 415
346 416
417 class MiscTracebackCases(unittest.TestCase):
418 #
419 # Check non-printing functions in traceback module
420 #
421
422 def test_clear(self):
423 def outer():
424 middle()
425 def middle():
426 inner()
427 def inner():
428 i = 1
429 1/0
430
431 try:
432 outer()
433 except:
434 type_, value, tb = sys.exc_info()
435
436 # Initial assertion: there's one local in the inner frame.
437 inner_frame = tb.tb_next.tb_next.tb_next.tb_frame
438 self.assertEqual(len(inner_frame.f_locals), 1)
439
440 # Clear traceback frames
441 traceback.clear_frames(tb)
442
443 # Local variable dict should now be empty.
444 self.assertEqual(len(inner_frame.f_locals), 0)
445
446
347 def test_main(): 447 def test_main():
348 run_unittest(__name__) 448 run_unittest(__name__)
349 449
350 if __name__ == "__main__": 450 if __name__ == "__main__":
351 test_main() 451 test_main()
LEFTRIGHT

RSS Feeds Recent Issues | This issue
This is Rietveld 894c83f36cb7+