##// END OF EJS Templates
Update doctests. Use repr when showing variables
Alex Hall -
Show More
@@ -1,246 +1,237 b''
1 1 """Tests for the key interactiveshell module, where the main ipython class is defined.
2 2 """
3 3 #-----------------------------------------------------------------------------
4 4 # Module imports
5 5 #-----------------------------------------------------------------------------
6 6
7 7 # third party
8 8 import nose.tools as nt
9 9
10 10 # our own packages
11 11
12 12 #-----------------------------------------------------------------------------
13 13 # Test functions
14 14 #-----------------------------------------------------------------------------
15 15
16 16 def test_reset():
17 17 """reset must clear most namespaces."""
18 18
19 19 # Check that reset runs without error
20 20 ip.reset()
21 21
22 22 # Once we've reset it (to clear of any junk that might have been there from
23 23 # other tests, we can count how many variables are in the user's namespace
24 24 nvars_user_ns = len(ip.user_ns)
25 25 nvars_hidden = len(ip.user_ns_hidden)
26 26
27 27 # Now add a few variables to user_ns, and check that reset clears them
28 28 ip.user_ns['x'] = 1
29 29 ip.user_ns['y'] = 1
30 30 ip.reset()
31 31
32 32 # Finally, check that all namespaces have only as many variables as we
33 33 # expect to find in them:
34 34 nt.assert_equal(len(ip.user_ns), nvars_user_ns)
35 35 nt.assert_equal(len(ip.user_ns_hidden), nvars_hidden)
36 36
37 37
38 38 # Tests for reporting of exceptions in various modes, handling of SystemExit,
39 39 # and %tb functionality. This is really a mix of testing ultraTB and interactiveshell.
40 40
41 41 def doctest_tb_plain():
42 42 """
43 43 In [18]: xmode plain
44 44 Exception reporting mode: Plain
45 45
46 46 In [19]: run simpleerr.py
47 47 Traceback (most recent call last):
48 48 ...line 32, in <module>
49 49 bar(mode)
50 50 ...line 16, in bar
51 51 div0()
52 52 ...line 8, in div0
53 53 x/y
54 54 ZeroDivisionError: ...
55 55 """
56 56
57 57
58 58 def doctest_tb_context():
59 59 """
60 60 In [3]: xmode context
61 61 Exception reporting mode: Context
62 62
63 63 In [4]: run simpleerr.py
64 64 ---------------------------------------------------------------------------
65 65 ZeroDivisionError Traceback (most recent call last)
66 66 <BLANKLINE>
67 67 ... in <module>
68 29 except IndexError:
68 69 30 mode = 'div'
69 31
70 70 ---> 32 bar(mode)
71 71 <BLANKLINE>
72 72 ... in bar(mode)
73 73 14 "bar"
74 74 15 if mode=='div':
75 75 ---> 16 div0()
76 76 17 elif mode=='exit':
77 77 18 try:
78 78 <BLANKLINE>
79 79 ... in div0()
80 80 6 x = 1
81 81 7 y = 0
82 82 ----> 8 x/y
83 9
84 10 def sysexit(stat, mode):
85 83 <BLANKLINE>
86 84 ZeroDivisionError: ...
87 85 """
88 86
89 87
90 88 def doctest_tb_verbose():
91 89 """
92 90 In [5]: xmode verbose
93 91 Exception reporting mode: Verbose
94 92
95 93 In [6]: run simpleerr.py
96 94 ---------------------------------------------------------------------------
97 95 ZeroDivisionError Traceback (most recent call last)
98 96 <BLANKLINE>
99 97 ... in <module>
98 29 except IndexError:
100 99 30 mode = 'div'
101 31
102 100 ---> 32 bar(mode)
103 global bar = <function bar at ...>
104 global mode = 'div'
101 mode = 'div'
105 102 <BLANKLINE>
106 103 ... in bar(mode='div')
107 104 14 "bar"
108 105 15 if mode=='div':
109 106 ---> 16 div0()
110 global div0 = <function div0 at ...>
111 107 17 elif mode=='exit':
112 108 18 try:
113 109 <BLANKLINE>
114 110 ... in div0()
115 111 6 x = 1
116 112 7 y = 0
117 113 ----> 8 x/y
118 114 x = 1
119 115 y = 0
120 9
121 10 def sysexit(stat, mode):
122 116 <BLANKLINE>
123 117 ZeroDivisionError: ...
124 118 """
125 119
126 120 def doctest_tb_sysexit():
127 121 """
128 122 In [17]: %xmode plain
129 123 Exception reporting mode: Plain
130 124
131 125 In [18]: %run simpleerr.py exit
132 126 An exception has occurred, use %tb to see the full traceback.
133 127 SystemExit: (1, 'Mode = exit')
134 128
135 129 In [19]: %run simpleerr.py exit 2
136 130 An exception has occurred, use %tb to see the full traceback.
137 131 SystemExit: (2, 'Mode = exit')
138 132
139 133 In [20]: %tb
140 134 Traceback (most recent call last):
141 135 File ... in <module>
142 136 bar(mode)
143 137 File ... line 22, in bar
144 138 sysexit(stat, mode)
145 139 File ... line 11, in sysexit
146 140 raise SystemExit(stat, 'Mode = %s' % mode)
147 141 SystemExit: (2, 'Mode = exit')
148 142
149 143 In [21]: %xmode context
150 144 Exception reporting mode: Context
151 145
152 146 In [22]: %tb
153 147 ---------------------------------------------------------------------------
154 148 SystemExit Traceback (most recent call last)
155 149 <BLANKLINE>
156 150 ...<module>
151 29 except IndexError:
157 152 30 mode = 'div'
158 31
159 153 ---> 32 bar(mode)
160 154 <BLANKLINE>
161 155 ...bar(mode)
162 156 20 except:
163 157 21 stat = 1
164 158 ---> 22 sysexit(stat, mode)
165 159 23 else:
166 160 24 raise ValueError('Unknown mode')
167 161 <BLANKLINE>
168 162 ...sysexit(stat, mode)
169 9
170 163 10 def sysexit(stat, mode):
171 164 ---> 11 raise SystemExit(stat, 'Mode = %s' % mode)
172 12
173 13 def bar(mode):
174 165 <BLANKLINE>
175 166 SystemExit: (2, 'Mode = exit')
176 167
177 168 In [23]: %xmode verbose
178 169 Exception reporting mode: Verbose
179 170
180 171 In [24]: %tb
181 172 ---------------------------------------------------------------------------
182 173 SystemExit Traceback (most recent call last)
183 174 <BLANKLINE>
184 175 ... in <module>
185 176 30 mode = 'div'
186 177 31
187 178 ---> 32 bar(mode)
188 179 global bar = <function bar at ...>
189 180 global mode = 'exit'
190 181 <BLANKLINE>
191 182 ... in bar(mode='exit')
192 183 20 except:
193 184 21 stat = 1
194 185 ---> 22 sysexit(stat, mode)
195 186 global sysexit = <function sysexit at ...>
196 187 stat = 2
197 188 mode = 'exit'
198 189 23 else:
199 190 24 raise ValueError('Unknown mode')
200 191 <BLANKLINE>
201 192 ... in sysexit(stat=2, mode='exit')
202 193 9
203 194 10 def sysexit(stat, mode):
204 195 ---> 11 raise SystemExit(stat, 'Mode = %s' % mode)
205 196 global SystemExit = undefined
206 197 stat = 2
207 198 mode = 'exit'
208 199 12
209 200 13 def bar(mode):
210 201 <BLANKLINE>
211 202 SystemExit: (2, 'Mode = exit')
212 203 """
213 204
214 205
215 206 def test_run_cell():
216 207 import textwrap
217 208 ip.run_cell('a = 10\na+=1')
218 209 ip.run_cell('assert a == 11\nassert 1')
219 210
220 211 nt.assert_equal(ip.user_ns['a'], 11)
221 212 complex = textwrap.dedent("""
222 213 if 1:
223 214 print "hello"
224 215 if 1:
225 216 print "world"
226 217
227 218 if 2:
228 219 print "foo"
229 220
230 221 if 3:
231 222 print "bar"
232 223
233 224 if 4:
234 225 print "bar"
235 226
236 227 """)
237 228 # Simply verifies that this kind of input is run
238 229 ip.run_cell(complex)
239 230
240 231
241 232 def test_db():
242 233 """Test the internal database used for variable persistence."""
243 234 ip.db['__unittest_'] = 12
244 235 nt.assert_equal(ip.db['__unittest_'], 12)
245 236 del ip.db['__unittest_']
246 237 assert '__unittest_' not in ip.db
@@ -1,1066 +1,1066 b''
1 1 # -*- coding: utf-8 -*-
2 2 """
3 3 Verbose and colourful traceback formatting.
4 4
5 5 **ColorTB**
6 6
7 7 I've always found it a bit hard to visually parse tracebacks in Python. The
8 8 ColorTB class is a solution to that problem. It colors the different parts of a
9 9 traceback in a manner similar to what you would expect from a syntax-highlighting
10 10 text editor.
11 11
12 12 Installation instructions for ColorTB::
13 13
14 14 import sys,ultratb
15 15 sys.excepthook = ultratb.ColorTB()
16 16
17 17 **VerboseTB**
18 18
19 19 I've also included a port of Ka-Ping Yee's "cgitb.py" that produces all kinds
20 20 of useful info when a traceback occurs. Ping originally had it spit out HTML
21 21 and intended it for CGI programmers, but why should they have all the fun? I
22 22 altered it to spit out colored text to the terminal. It's a bit overwhelming,
23 23 but kind of neat, and maybe useful for long-running programs that you believe
24 24 are bug-free. If a crash *does* occur in that type of program you want details.
25 25 Give it a shot--you'll love it or you'll hate it.
26 26
27 27 .. note::
28 28
29 29 The Verbose mode prints the variables currently visible where the exception
30 30 happened (shortening their strings if too long). This can potentially be
31 31 very slow, if you happen to have a huge data structure whose string
32 32 representation is complex to compute. Your computer may appear to freeze for
33 33 a while with cpu usage at 100%. If this occurs, you can cancel the traceback
34 34 with Ctrl-C (maybe hitting it more than once).
35 35
36 36 If you encounter this kind of situation often, you may want to use the
37 37 Verbose_novars mode instead of the regular Verbose, which avoids formatting
38 38 variables (but otherwise includes the information and context given by
39 39 Verbose).
40 40
41 41 .. note::
42 42
43 43 The verbose mode print all variables in the stack, which means it can
44 44 potentially leak sensitive information like access keys, or unencrypted
45 45 password.
46 46
47 47 Installation instructions for VerboseTB::
48 48
49 49 import sys,ultratb
50 50 sys.excepthook = ultratb.VerboseTB()
51 51
52 52 Note: Much of the code in this module was lifted verbatim from the standard
53 53 library module 'traceback.py' and Ka-Ping Yee's 'cgitb.py'.
54 54
55 55 Color schemes
56 56 -------------
57 57
58 58 The colors are defined in the class TBTools through the use of the
59 59 ColorSchemeTable class. Currently the following exist:
60 60
61 61 - NoColor: allows all of this module to be used in any terminal (the color
62 62 escapes are just dummy blank strings).
63 63
64 64 - Linux: is meant to look good in a terminal like the Linux console (black
65 65 or very dark background).
66 66
67 67 - LightBG: similar to Linux but swaps dark/light colors to be more readable
68 68 in light background terminals.
69 69
70 70 - Neutral: a neutral color scheme that should be readable on both light and
71 71 dark background
72 72
73 73 You can implement other color schemes easily, the syntax is fairly
74 74 self-explanatory. Please send back new schemes you develop to the author for
75 75 possible inclusion in future releases.
76 76
77 77 Inheritance diagram:
78 78
79 79 .. inheritance-diagram:: IPython.core.ultratb
80 80 :parts: 3
81 81 """
82 82
83 83 #*****************************************************************************
84 84 # Copyright (C) 2001 Nathaniel Gray <n8gray@caltech.edu>
85 85 # Copyright (C) 2001-2004 Fernando Perez <fperez@colorado.edu>
86 86 #
87 87 # Distributed under the terms of the BSD License. The full license is in
88 88 # the file COPYING, distributed as part of this software.
89 89 #*****************************************************************************
90 90
91 91
92 92 import inspect
93 93 import linecache
94 94 import pydoc
95 95 import sys
96 96 import time
97 97 import tokenize
98 98 import traceback
99 99
100 100 import stack_data
101 101
102 102 try: # Python 2
103 103 generate_tokens = tokenize.generate_tokens
104 104 except AttributeError: # Python 3
105 105 generate_tokens = tokenize.tokenize
106 106
107 107 # IPython's own modules
108 108 from IPython import get_ipython
109 109 from IPython.core import debugger
110 110 from IPython.core.display_trap import DisplayTrap
111 111 from IPython.core.excolors import exception_colors
112 112 from IPython.utils import PyColorize
113 113 from IPython.utils import path as util_path
114 114 from IPython.utils import py3compat
115 115 from IPython.utils.terminal import get_terminal_size
116 116
117 117 import IPython.utils.colorable as colorable
118 118
119 119 # Globals
120 120 # amount of space to put line numbers before verbose tracebacks
121 121 INDENT_SIZE = 8
122 122
123 123 # Default color scheme. This is used, for example, by the traceback
124 124 # formatter. When running in an actual IPython instance, the user's rc.colors
125 125 # value is used, but having a module global makes this functionality available
126 126 # to users of ultratb who are NOT running inside ipython.
127 127 DEFAULT_SCHEME = 'NoColor'
128 128
129 129 # ---------------------------------------------------------------------------
130 130 # Code begins
131 131
132 132 # Helper function -- largely belongs to VerboseTB, but we need the same
133 133 # functionality to produce a pseudo verbose TB for SyntaxErrors, so that they
134 134 # can be recognized properly by ipython.el's py-traceback-line-re
135 135 # (SyntaxErrors have to be treated specially because they have no traceback)
136 136
137 137
138 138 def _format_traceback_lines(lines, Colors, lvals, _line_format):
139 139 """
140 140 Format tracebacks lines with pointing arrow, leading numbers...
141 141
142 142 Parameters
143 143 ==========
144 144
145 145 lines: list[Line]
146 146 Colors:
147 147 ColorScheme used.
148 148 lvals: str
149 149 Values of local variables, already colored, to inject just after the error line.
150 150 _line_format: f (str) -> (str, bool)
151 151 return (colorized version of str, failure to do so)
152 152 """
153 153 numbers_width = INDENT_SIZE - 1
154 154 res = []
155 155
156 156 for stack_line in lines:
157 157 if stack_line is stack_data.LINE_GAP:
158 158 res.append('%s (...)%s\n' % (Colors.linenoEm, Colors.Normal))
159 159 continue
160 160
161 161 line = stack_line.text.rstrip('\n') + '\n'
162 162
163 163 new_line, err = _line_format(line, 'str')
164 164 if not err:
165 165 line = new_line
166 166
167 167 lineno = stack_line.lineno
168 168 if stack_line.is_current:
169 169 # This is the line with the error
170 170 pad = numbers_width - len(str(lineno))
171 171 num = '%s%s' % (debugger.make_arrow(pad), str(lineno))
172 172 line = '%s%s%s %s%s' % (Colors.linenoEm, num,
173 173 Colors.line, line, Colors.Normal)
174 174 else:
175 175 num = '%*s' % (numbers_width, lineno)
176 176 line = '%s%s%s %s' % (Colors.lineno, num,
177 177 Colors.Normal, line)
178 178
179 179 res.append(line)
180 180 if lvals and stack_line.is_current:
181 181 res.append(lvals + '\n')
182 182 return res
183 183
184 184
185 185 #---------------------------------------------------------------------------
186 186 # Module classes
187 187 class TBTools(colorable.Colorable):
188 188 """Basic tools used by all traceback printer classes."""
189 189
190 190 # Number of frames to skip when reporting tracebacks
191 191 tb_offset = 0
192 192
193 193 def __init__(self, color_scheme='NoColor', call_pdb=False, ostream=None, parent=None, config=None):
194 194 # Whether to call the interactive pdb debugger after printing
195 195 # tracebacks or not
196 196 super(TBTools, self).__init__(parent=parent, config=config)
197 197 self.call_pdb = call_pdb
198 198
199 199 # Output stream to write to. Note that we store the original value in
200 200 # a private attribute and then make the public ostream a property, so
201 201 # that we can delay accessing sys.stdout until runtime. The way
202 202 # things are written now, the sys.stdout object is dynamically managed
203 203 # so a reference to it should NEVER be stored statically. This
204 204 # property approach confines this detail to a single location, and all
205 205 # subclasses can simply access self.ostream for writing.
206 206 self._ostream = ostream
207 207
208 208 # Create color table
209 209 self.color_scheme_table = exception_colors()
210 210
211 211 self.set_colors(color_scheme)
212 212 self.old_scheme = color_scheme # save initial value for toggles
213 213
214 214 if call_pdb:
215 215 self.pdb = debugger.Pdb()
216 216 else:
217 217 self.pdb = None
218 218
219 219 def _get_ostream(self):
220 220 """Output stream that exceptions are written to.
221 221
222 222 Valid values are:
223 223
224 224 - None: the default, which means that IPython will dynamically resolve
225 225 to sys.stdout. This ensures compatibility with most tools, including
226 226 Windows (where plain stdout doesn't recognize ANSI escapes).
227 227
228 228 - Any object with 'write' and 'flush' attributes.
229 229 """
230 230 return sys.stdout if self._ostream is None else self._ostream
231 231
232 232 def _set_ostream(self, val):
233 233 assert val is None or (hasattr(val, 'write') and hasattr(val, 'flush'))
234 234 self._ostream = val
235 235
236 236 ostream = property(_get_ostream, _set_ostream)
237 237
238 238 def get_parts_of_chained_exception(self, evalue):
239 239 def get_chained_exception(exception_value):
240 240 cause = getattr(exception_value, '__cause__', None)
241 241 if cause:
242 242 return cause
243 243 if getattr(exception_value, '__suppress_context__', False):
244 244 return None
245 245 return getattr(exception_value, '__context__', None)
246 246
247 247 chained_evalue = get_chained_exception(evalue)
248 248
249 249 if chained_evalue:
250 250 return chained_evalue.__class__, chained_evalue, chained_evalue.__traceback__
251 251
252 252 def prepare_chained_exception_message(self, cause):
253 253 direct_cause = "\nThe above exception was the direct cause of the following exception:\n"
254 254 exception_during_handling = "\nDuring handling of the above exception, another exception occurred:\n"
255 255
256 256 if cause:
257 257 message = [[direct_cause]]
258 258 else:
259 259 message = [[exception_during_handling]]
260 260 return message
261 261
262 262 def set_colors(self, *args, **kw):
263 263 """Shorthand access to the color table scheme selector method."""
264 264
265 265 # Set own color table
266 266 self.color_scheme_table.set_active_scheme(*args, **kw)
267 267 # for convenience, set Colors to the active scheme
268 268 self.Colors = self.color_scheme_table.active_colors
269 269 # Also set colors of debugger
270 270 if hasattr(self, 'pdb') and self.pdb is not None:
271 271 self.pdb.set_colors(*args, **kw)
272 272
273 273 def color_toggle(self):
274 274 """Toggle between the currently active color scheme and NoColor."""
275 275
276 276 if self.color_scheme_table.active_scheme_name == 'NoColor':
277 277 self.color_scheme_table.set_active_scheme(self.old_scheme)
278 278 self.Colors = self.color_scheme_table.active_colors
279 279 else:
280 280 self.old_scheme = self.color_scheme_table.active_scheme_name
281 281 self.color_scheme_table.set_active_scheme('NoColor')
282 282 self.Colors = self.color_scheme_table.active_colors
283 283
284 284 def stb2text(self, stb):
285 285 """Convert a structured traceback (a list) to a string."""
286 286 return '\n'.join(stb)
287 287
288 288 def text(self, etype, value, tb, tb_offset=None, context=5):
289 289 """Return formatted traceback.
290 290
291 291 Subclasses may override this if they add extra arguments.
292 292 """
293 293 tb_list = self.structured_traceback(etype, value, tb,
294 294 tb_offset, context)
295 295 return self.stb2text(tb_list)
296 296
297 297 def structured_traceback(self, etype, evalue, tb, tb_offset=None,
298 298 context=5, mode=None):
299 299 """Return a list of traceback frames.
300 300
301 301 Must be implemented by each class.
302 302 """
303 303 raise NotImplementedError()
304 304
305 305
306 306 #---------------------------------------------------------------------------
307 307 class ListTB(TBTools):
308 308 """Print traceback information from a traceback list, with optional color.
309 309
310 310 Calling requires 3 arguments: (etype, evalue, elist)
311 311 as would be obtained by::
312 312
313 313 etype, evalue, tb = sys.exc_info()
314 314 if tb:
315 315 elist = traceback.extract_tb(tb)
316 316 else:
317 317 elist = None
318 318
319 319 It can thus be used by programs which need to process the traceback before
320 320 printing (such as console replacements based on the code module from the
321 321 standard library).
322 322
323 323 Because they are meant to be called without a full traceback (only a
324 324 list), instances of this class can't call the interactive pdb debugger."""
325 325
326 326 def __init__(self, color_scheme='NoColor', call_pdb=False, ostream=None, parent=None, config=None):
327 327 TBTools.__init__(self, color_scheme=color_scheme, call_pdb=call_pdb,
328 328 ostream=ostream, parent=parent,config=config)
329 329
330 330 def __call__(self, etype, value, elist):
331 331 self.ostream.flush()
332 332 self.ostream.write(self.text(etype, value, elist))
333 333 self.ostream.write('\n')
334 334
335 335 def _extract_tb(self, tb):
336 336 if tb:
337 337 return traceback.extract_tb(tb)
338 338 else:
339 339 return None
340 340
341 341 def structured_traceback(self, etype, evalue, etb=None, tb_offset=None,
342 342 context=5):
343 343 """Return a color formatted string with the traceback info.
344 344
345 345 Parameters
346 346 ----------
347 347 etype : exception type
348 348 Type of the exception raised.
349 349
350 350 evalue : object
351 351 Data stored in the exception
352 352
353 353 etb : object
354 354 If list: List of frames, see class docstring for details.
355 355 If Traceback: Traceback of the exception.
356 356
357 357 tb_offset : int, optional
358 358 Number of frames in the traceback to skip. If not given, the
359 359 instance evalue is used (set in constructor).
360 360
361 361 context : int, optional
362 362 Number of lines of context information to print.
363 363
364 364 Returns
365 365 -------
366 366 String with formatted exception.
367 367 """
368 368 # This is a workaround to get chained_exc_ids in recursive calls
369 369 # etb should not be a tuple if structured_traceback is not recursive
370 370 if isinstance(etb, tuple):
371 371 etb, chained_exc_ids = etb
372 372 else:
373 373 chained_exc_ids = set()
374 374
375 375 if isinstance(etb, list):
376 376 elist = etb
377 377 elif etb is not None:
378 378 elist = self._extract_tb(etb)
379 379 else:
380 380 elist = []
381 381 tb_offset = self.tb_offset if tb_offset is None else tb_offset
382 382 Colors = self.Colors
383 383 out_list = []
384 384 if elist:
385 385
386 386 if tb_offset and len(elist) > tb_offset:
387 387 elist = elist[tb_offset:]
388 388
389 389 out_list.append('Traceback %s(most recent call last)%s:' %
390 390 (Colors.normalEm, Colors.Normal) + '\n')
391 391 out_list.extend(self._format_list(elist))
392 392 # The exception info should be a single entry in the list.
393 393 lines = ''.join(self._format_exception_only(etype, evalue))
394 394 out_list.append(lines)
395 395
396 396 exception = self.get_parts_of_chained_exception(evalue)
397 397
398 398 if exception and not id(exception[1]) in chained_exc_ids:
399 399 chained_exception_message = self.prepare_chained_exception_message(
400 400 evalue.__cause__)[0]
401 401 etype, evalue, etb = exception
402 402 # Trace exception to avoid infinite 'cause' loop
403 403 chained_exc_ids.add(id(exception[1]))
404 404 chained_exceptions_tb_offset = 0
405 405 out_list = (
406 406 self.structured_traceback(
407 407 etype, evalue, (etb, chained_exc_ids),
408 408 chained_exceptions_tb_offset, context)
409 409 + chained_exception_message
410 410 + out_list)
411 411
412 412 return out_list
413 413
414 414 def _format_list(self, extracted_list):
415 415 """Format a list of traceback entry tuples for printing.
416 416
417 417 Given a list of tuples as returned by extract_tb() or
418 418 extract_stack(), return a list of strings ready for printing.
419 419 Each string in the resulting list corresponds to the item with the
420 420 same index in the argument list. Each string ends in a newline;
421 421 the strings may contain internal newlines as well, for those items
422 422 whose source text line is not None.
423 423
424 424 Lifted almost verbatim from traceback.py
425 425 """
426 426
427 427 Colors = self.Colors
428 428 list = []
429 429 for filename, lineno, name, line in extracted_list[:-1]:
430 430 item = ' File %s"%s"%s, line %s%d%s, in %s%s%s\n' % \
431 431 (Colors.filename, filename, Colors.Normal,
432 432 Colors.lineno, lineno, Colors.Normal,
433 433 Colors.name, name, Colors.Normal)
434 434 if line:
435 435 item += ' %s\n' % line.strip()
436 436 list.append(item)
437 437 # Emphasize the last entry
438 438 filename, lineno, name, line = extracted_list[-1]
439 439 item = '%s File %s"%s"%s, line %s%d%s, in %s%s%s%s\n' % \
440 440 (Colors.normalEm,
441 441 Colors.filenameEm, filename, Colors.normalEm,
442 442 Colors.linenoEm, lineno, Colors.normalEm,
443 443 Colors.nameEm, name, Colors.normalEm,
444 444 Colors.Normal)
445 445 if line:
446 446 item += '%s %s%s\n' % (Colors.line, line.strip(),
447 447 Colors.Normal)
448 448 list.append(item)
449 449 return list
450 450
451 451 def _format_exception_only(self, etype, value):
452 452 """Format the exception part of a traceback.
453 453
454 454 The arguments are the exception type and value such as given by
455 455 sys.exc_info()[:2]. The return value is a list of strings, each ending
456 456 in a newline. Normally, the list contains a single string; however,
457 457 for SyntaxError exceptions, it contains several lines that (when
458 458 printed) display detailed information about where the syntax error
459 459 occurred. The message indicating which exception occurred is the
460 460 always last string in the list.
461 461
462 462 Also lifted nearly verbatim from traceback.py
463 463 """
464 464 have_filedata = False
465 465 Colors = self.Colors
466 466 list = []
467 467 stype = py3compat.cast_unicode(Colors.excName + etype.__name__ + Colors.Normal)
468 468 if value is None:
469 469 # Not sure if this can still happen in Python 2.6 and above
470 470 list.append(stype + '\n')
471 471 else:
472 472 if issubclass(etype, SyntaxError):
473 473 have_filedata = True
474 474 if not value.filename: value.filename = "<string>"
475 475 if value.lineno:
476 476 lineno = value.lineno
477 477 textline = linecache.getline(value.filename, value.lineno)
478 478 else:
479 479 lineno = 'unknown'
480 480 textline = ''
481 481 list.append('%s File %s"%s"%s, line %s%s%s\n' % \
482 482 (Colors.normalEm,
483 483 Colors.filenameEm, py3compat.cast_unicode(value.filename), Colors.normalEm,
484 484 Colors.linenoEm, lineno, Colors.Normal ))
485 485 if textline == '':
486 486 textline = py3compat.cast_unicode(value.text, "utf-8")
487 487
488 488 if textline is not None:
489 489 i = 0
490 490 while i < len(textline) and textline[i].isspace():
491 491 i += 1
492 492 list.append('%s %s%s\n' % (Colors.line,
493 493 textline.strip(),
494 494 Colors.Normal))
495 495 if value.offset is not None:
496 496 s = ' '
497 497 for c in textline[i:value.offset - 1]:
498 498 if c.isspace():
499 499 s += c
500 500 else:
501 501 s += ' '
502 502 list.append('%s%s^%s\n' % (Colors.caret, s,
503 503 Colors.Normal))
504 504
505 505 try:
506 506 s = value.msg
507 507 except Exception:
508 508 s = self._some_str(value)
509 509 if s:
510 510 list.append('%s%s:%s %s\n' % (stype, Colors.excName,
511 511 Colors.Normal, s))
512 512 else:
513 513 list.append('%s\n' % stype)
514 514
515 515 # sync with user hooks
516 516 if have_filedata:
517 517 ipinst = get_ipython()
518 518 if ipinst is not None:
519 519 ipinst.hooks.synchronize_with_editor(value.filename, value.lineno, 0)
520 520
521 521 return list
522 522
523 523 def get_exception_only(self, etype, value):
524 524 """Only print the exception type and message, without a traceback.
525 525
526 526 Parameters
527 527 ----------
528 528 etype : exception type
529 529 value : exception value
530 530 """
531 531 return ListTB.structured_traceback(self, etype, value)
532 532
533 533 def show_exception_only(self, etype, evalue):
534 534 """Only print the exception type and message, without a traceback.
535 535
536 536 Parameters
537 537 ----------
538 538 etype : exception type
539 539 value : exception value
540 540 """
541 541 # This method needs to use __call__ from *this* class, not the one from
542 542 # a subclass whose signature or behavior may be different
543 543 ostream = self.ostream
544 544 ostream.flush()
545 545 ostream.write('\n'.join(self.get_exception_only(etype, evalue)))
546 546 ostream.flush()
547 547
548 548 def _some_str(self, value):
549 549 # Lifted from traceback.py
550 550 try:
551 551 return py3compat.cast_unicode(str(value))
552 552 except:
553 553 return u'<unprintable %s object>' % type(value).__name__
554 554
555 555
556 556 #----------------------------------------------------------------------------
557 557 class VerboseTB(TBTools):
558 558 """A port of Ka-Ping Yee's cgitb.py module that outputs color text instead
559 559 of HTML. Requires inspect and pydoc. Crazy, man.
560 560
561 561 Modified version which optionally strips the topmost entries from the
562 562 traceback, to be used with alternate interpreters (because their own code
563 563 would appear in the traceback)."""
564 564
565 565 def __init__(self, color_scheme='Linux', call_pdb=False, ostream=None,
566 566 tb_offset=0, long_header=False, include_vars=True,
567 567 check_cache=None, debugger_cls = None,
568 568 parent=None, config=None):
569 569 """Specify traceback offset, headers and color scheme.
570 570
571 571 Define how many frames to drop from the tracebacks. Calling it with
572 572 tb_offset=1 allows use of this handler in interpreters which will have
573 573 their own code at the top of the traceback (VerboseTB will first
574 574 remove that frame before printing the traceback info)."""
575 575 TBTools.__init__(self, color_scheme=color_scheme, call_pdb=call_pdb,
576 576 ostream=ostream, parent=parent, config=config)
577 577 self.tb_offset = tb_offset
578 578 self.long_header = long_header
579 579 self.include_vars = include_vars
580 580 # By default we use linecache.checkcache, but the user can provide a
581 581 # different check_cache implementation. This is used by the IPython
582 582 # kernel to provide tracebacks for interactive code that is cached,
583 583 # by a compiler instance that flushes the linecache but preserves its
584 584 # own code cache.
585 585 if check_cache is None:
586 586 check_cache = linecache.checkcache
587 587 self.check_cache = check_cache
588 588
589 589 self.debugger_cls = debugger_cls or debugger.Pdb
590 590
591 591 def format_record(self, frame_info):
592 592 """Format a single stack frame"""
593 593 Colors = self.Colors # just a shorthand + quicker name lookup
594 594 ColorsNormal = Colors.Normal # used a lot
595 595
596 596 if isinstance(frame_info, stack_data.RepeatedFrames):
597 597 return ' %s[... skipping similar frames: %s]%s\n' % (
598 598 Colors.excName, frame_info.description, ColorsNormal)
599 599
600 600 col_scheme = self.color_scheme_table.active_scheme_name
601 601 indent = ' ' * INDENT_SIZE
602 602 em_normal = '%s\n%s%s' % (Colors.valEm, indent, ColorsNormal)
603 603 tpl_link = '%s%%s%s' % (Colors.filenameEm, ColorsNormal)
604 604 tpl_call = 'in %s%%s%s%%s%s' % (Colors.vName, Colors.valEm,
605 605 ColorsNormal)
606 606 tpl_call_fail = 'in %s%%s%s(***failed resolving arguments***)%s' % \
607 607 (Colors.vName, Colors.valEm, ColorsNormal)
608 608 tpl_local_var = '%s%%s%s' % (Colors.vName, ColorsNormal)
609 609 tpl_name_val = '%%s %s= %%s%s' % (Colors.valEm, ColorsNormal)
610 610
611 611 file = frame_info.filename
612 612 file = py3compat.cast_unicode(file, util_path.fs_encoding)
613 613 link = tpl_link % util_path.compress_user(file)
614 614 args, varargs, varkw, locals_ = inspect.getargvalues(frame_info.frame)
615 615
616 616 func = frame_info.executing.code_qualname()
617 617 if func == '<module>':
618 618 call = tpl_call % (func, '')
619 619 else:
620 620 # Decide whether to include variable details or not
621 621 var_repr = eqrepr if self.include_vars else nullrepr
622 622 try:
623 623 call = tpl_call % (func, inspect.formatargvalues(args,
624 624 varargs, varkw,
625 625 locals_, formatvalue=var_repr))
626 626 except KeyError:
627 627 # This happens in situations like errors inside generator
628 628 # expressions, where local variables are listed in the
629 629 # line, but can't be extracted from the frame. I'm not
630 630 # 100% sure this isn't actually a bug in inspect itself,
631 631 # but since there's no info for us to compute with, the
632 632 # best we can do is report the failure and move on. Here
633 633 # we must *not* call any traceback construction again,
634 634 # because that would mess up use of %debug later on. So we
635 635 # simply report the failure and move on. The only
636 636 # limitation will be that this frame won't have locals
637 637 # listed in the call signature. Quite subtle problem...
638 638 # I can't think of a good way to validate this in a unit
639 639 # test, but running a script consisting of:
640 640 # dict( (k,v.strip()) for (k,v) in range(10) )
641 641 # will illustrate the error, if this exception catch is
642 642 # disabled.
643 643 call = tpl_call_fail % func
644 644
645 645 lvals = ''
646 646 lvals_list = []
647 647 if self.include_vars:
648 648 for var in frame_info.variables_in_executing_piece:
649 lvals_list.append(tpl_name_val % (var.name, var.value))
649 lvals_list.append(tpl_name_val % (var.name, repr(var.value)))
650 650 if lvals_list:
651 651 lvals = '%s%s' % (indent, em_normal.join(lvals_list))
652 652
653 653 result = '%s %s\n' % (link, call)
654 654
655 655 _line_format = PyColorize.Parser(style=col_scheme, parent=self).format2
656 656 result += ''.join(_format_traceback_lines(frame_info.lines, Colors, lvals, _line_format))
657 657 return result
658 658
659 659 def prepare_header(self, etype, long_version=False):
660 660 colors = self.Colors # just a shorthand + quicker name lookup
661 661 colorsnormal = colors.Normal # used a lot
662 662 exc = '%s%s%s' % (colors.excName, etype, colorsnormal)
663 663 width = min(75, get_terminal_size()[0])
664 664 if long_version:
665 665 # Header with the exception type, python version, and date
666 666 pyver = 'Python ' + sys.version.split()[0] + ': ' + sys.executable
667 667 date = time.ctime(time.time())
668 668
669 669 head = '%s%s%s\n%s%s%s\n%s' % (colors.topline, '-' * width, colorsnormal,
670 670 exc, ' ' * (width - len(str(etype)) - len(pyver)),
671 671 pyver, date.rjust(width) )
672 672 head += "\nA problem occurred executing Python code. Here is the sequence of function" \
673 673 "\ncalls leading up to the error, with the most recent (innermost) call last."
674 674 else:
675 675 # Simplified header
676 676 head = '%s%s' % (exc, 'Traceback (most recent call last)'. \
677 677 rjust(width - len(str(etype))) )
678 678
679 679 return head
680 680
681 681 def format_exception(self, etype, evalue):
682 682 colors = self.Colors # just a shorthand + quicker name lookup
683 683 colorsnormal = colors.Normal # used a lot
684 684 # Get (safely) a string form of the exception info
685 685 try:
686 686 etype_str, evalue_str = map(str, (etype, evalue))
687 687 except:
688 688 # User exception is improperly defined.
689 689 etype, evalue = str, sys.exc_info()[:2]
690 690 etype_str, evalue_str = map(str, (etype, evalue))
691 691 # ... and format it
692 692 return ['%s%s%s: %s' % (colors.excName, etype_str,
693 693 colorsnormal, py3compat.cast_unicode(evalue_str))]
694 694
695 695 def format_exception_as_a_whole(self, etype, evalue, etb, number_of_lines_of_context, tb_offset):
696 696 """Formats the header, traceback and exception message for a single exception.
697 697
698 698 This may be called multiple times by Python 3 exception chaining
699 699 (PEP 3134).
700 700 """
701 701 # some locals
702 702 orig_etype = etype
703 703 try:
704 704 etype = etype.__name__
705 705 except AttributeError:
706 706 pass
707 707
708 708 tb_offset = self.tb_offset if tb_offset is None else tb_offset
709 709 head = self.prepare_header(etype, self.long_header)
710 710 records = self.get_records(etb, number_of_lines_of_context, tb_offset)
711 711
712 712 frames = list(map(self.format_record, records))
713 713
714 714 formatted_exception = self.format_exception(etype, evalue)
715 715 if records:
716 716 frame_info = records[-1]
717 717 ipinst = get_ipython()
718 718 if ipinst is not None:
719 719 ipinst.hooks.synchronize_with_editor(frame_info.filename, frame_info.lineno, 0)
720 720
721 721 return [[head] + frames + [''.join(formatted_exception[0])]]
722 722
723 723 def get_records(self, etb, number_of_lines_of_context, tb_offset):
724 724 context = number_of_lines_of_context - 1
725 725 after = context // 2
726 726 before = context - after
727 727 options = stack_data.Options(before=before, after=after)
728 728 return list(stack_data.FrameInfo.stack_data(etb, options=options))[tb_offset:]
729 729
730 730 def structured_traceback(self, etype, evalue, etb, tb_offset=None,
731 731 number_of_lines_of_context=5):
732 732 """Return a nice text document describing the traceback."""
733 733
734 734 formatted_exception = self.format_exception_as_a_whole(etype, evalue, etb, number_of_lines_of_context,
735 735 tb_offset)
736 736
737 737 colors = self.Colors # just a shorthand + quicker name lookup
738 738 colorsnormal = colors.Normal # used a lot
739 739 head = '%s%s%s' % (colors.topline, '-' * min(75, get_terminal_size()[0]), colorsnormal)
740 740 structured_traceback_parts = [head]
741 741 chained_exceptions_tb_offset = 0
742 742 lines_of_context = 3
743 743 formatted_exceptions = formatted_exception
744 744 exception = self.get_parts_of_chained_exception(evalue)
745 745 if exception:
746 746 formatted_exceptions += self.prepare_chained_exception_message(evalue.__cause__)
747 747 etype, evalue, etb = exception
748 748 else:
749 749 evalue = None
750 750 chained_exc_ids = set()
751 751 while evalue:
752 752 formatted_exceptions += self.format_exception_as_a_whole(etype, evalue, etb, lines_of_context,
753 753 chained_exceptions_tb_offset)
754 754 exception = self.get_parts_of_chained_exception(evalue)
755 755
756 756 if exception and not id(exception[1]) in chained_exc_ids:
757 757 chained_exc_ids.add(id(exception[1])) # trace exception to avoid infinite 'cause' loop
758 758 formatted_exceptions += self.prepare_chained_exception_message(evalue.__cause__)
759 759 etype, evalue, etb = exception
760 760 else:
761 761 evalue = None
762 762
763 763 # we want to see exceptions in a reversed order:
764 764 # the first exception should be on top
765 765 for formatted_exception in reversed(formatted_exceptions):
766 766 structured_traceback_parts += formatted_exception
767 767
768 768 return structured_traceback_parts
769 769
770 770 def debugger(self, force=False):
771 771 """Call up the pdb debugger if desired, always clean up the tb
772 772 reference.
773 773
774 774 Keywords:
775 775
776 776 - force(False): by default, this routine checks the instance call_pdb
777 777 flag and does not actually invoke the debugger if the flag is false.
778 778 The 'force' option forces the debugger to activate even if the flag
779 779 is false.
780 780
781 781 If the call_pdb flag is set, the pdb interactive debugger is
782 782 invoked. In all cases, the self.tb reference to the current traceback
783 783 is deleted to prevent lingering references which hamper memory
784 784 management.
785 785
786 786 Note that each call to pdb() does an 'import readline', so if your app
787 787 requires a special setup for the readline completers, you'll have to
788 788 fix that by hand after invoking the exception handler."""
789 789
790 790 if force or self.call_pdb:
791 791 if self.pdb is None:
792 792 self.pdb = self.debugger_cls()
793 793 # the system displayhook may have changed, restore the original
794 794 # for pdb
795 795 display_trap = DisplayTrap(hook=sys.__displayhook__)
796 796 with display_trap:
797 797 self.pdb.reset()
798 798 # Find the right frame so we don't pop up inside ipython itself
799 799 if hasattr(self, 'tb') and self.tb is not None:
800 800 etb = self.tb
801 801 else:
802 802 etb = self.tb = sys.last_traceback
803 803 while self.tb is not None and self.tb.tb_next is not None:
804 804 self.tb = self.tb.tb_next
805 805 if etb and etb.tb_next:
806 806 etb = etb.tb_next
807 807 self.pdb.botframe = etb.tb_frame
808 808 self.pdb.interaction(None, etb)
809 809
810 810 if hasattr(self, 'tb'):
811 811 del self.tb
812 812
813 813 def handler(self, info=None):
814 814 (etype, evalue, etb) = info or sys.exc_info()
815 815 self.tb = etb
816 816 ostream = self.ostream
817 817 ostream.flush()
818 818 ostream.write(self.text(etype, evalue, etb))
819 819 ostream.write('\n')
820 820 ostream.flush()
821 821
822 822 # Changed so an instance can just be called as VerboseTB_inst() and print
823 823 # out the right info on its own.
824 824 def __call__(self, etype=None, evalue=None, etb=None):
825 825 """This hook can replace sys.excepthook (for Python 2.1 or higher)."""
826 826 if etb is None:
827 827 self.handler()
828 828 else:
829 829 self.handler((etype, evalue, etb))
830 830 try:
831 831 self.debugger()
832 832 except KeyboardInterrupt:
833 833 print("\nKeyboardInterrupt")
834 834
835 835
836 836 #----------------------------------------------------------------------------
837 837 class FormattedTB(VerboseTB, ListTB):
838 838 """Subclass ListTB but allow calling with a traceback.
839 839
840 840 It can thus be used as a sys.excepthook for Python > 2.1.
841 841
842 842 Also adds 'Context' and 'Verbose' modes, not available in ListTB.
843 843
844 844 Allows a tb_offset to be specified. This is useful for situations where
845 845 one needs to remove a number of topmost frames from the traceback (such as
846 846 occurs with python programs that themselves execute other python code,
847 847 like Python shells). """
848 848
849 849 def __init__(self, mode='Plain', color_scheme='Linux', call_pdb=False,
850 850 ostream=None,
851 851 tb_offset=0, long_header=False, include_vars=False,
852 852 check_cache=None, debugger_cls=None,
853 853 parent=None, config=None):
854 854
855 855 # NEVER change the order of this list. Put new modes at the end:
856 856 self.valid_modes = ['Plain', 'Context', 'Verbose', 'Minimal']
857 857 self.verbose_modes = self.valid_modes[1:3]
858 858
859 859 VerboseTB.__init__(self, color_scheme=color_scheme, call_pdb=call_pdb,
860 860 ostream=ostream, tb_offset=tb_offset,
861 861 long_header=long_header, include_vars=include_vars,
862 862 check_cache=check_cache, debugger_cls=debugger_cls,
863 863 parent=parent, config=config)
864 864
865 865 # Different types of tracebacks are joined with different separators to
866 866 # form a single string. They are taken from this dict
867 867 self._join_chars = dict(Plain='', Context='\n', Verbose='\n',
868 868 Minimal='')
869 869 # set_mode also sets the tb_join_char attribute
870 870 self.set_mode(mode)
871 871
872 872 def structured_traceback(self, etype, value, tb, tb_offset=None, number_of_lines_of_context=5):
873 873 tb_offset = self.tb_offset if tb_offset is None else tb_offset
874 874 mode = self.mode
875 875 if mode in self.verbose_modes:
876 876 # Verbose modes need a full traceback
877 877 return VerboseTB.structured_traceback(
878 878 self, etype, value, tb, tb_offset, number_of_lines_of_context
879 879 )
880 880 elif mode == 'Minimal':
881 881 return ListTB.get_exception_only(self, etype, value)
882 882 else:
883 883 # We must check the source cache because otherwise we can print
884 884 # out-of-date source code.
885 885 self.check_cache()
886 886 # Now we can extract and format the exception
887 887 return ListTB.structured_traceback(
888 888 self, etype, value, tb, tb_offset, number_of_lines_of_context
889 889 )
890 890
891 891 def stb2text(self, stb):
892 892 """Convert a structured traceback (a list) to a string."""
893 893 return self.tb_join_char.join(stb)
894 894
895 895
896 896 def set_mode(self, mode=None):
897 897 """Switch to the desired mode.
898 898
899 899 If mode is not specified, cycles through the available modes."""
900 900
901 901 if not mode:
902 902 new_idx = (self.valid_modes.index(self.mode) + 1 ) % \
903 903 len(self.valid_modes)
904 904 self.mode = self.valid_modes[new_idx]
905 905 elif mode not in self.valid_modes:
906 906 raise ValueError('Unrecognized mode in FormattedTB: <' + mode + '>\n'
907 907 'Valid modes: ' + str(self.valid_modes))
908 908 else:
909 909 self.mode = mode
910 910 # include variable details only in 'Verbose' mode
911 911 self.include_vars = (self.mode == self.valid_modes[2])
912 912 # Set the join character for generating text tracebacks
913 913 self.tb_join_char = self._join_chars[self.mode]
914 914
915 915 # some convenient shortcuts
916 916 def plain(self):
917 917 self.set_mode(self.valid_modes[0])
918 918
919 919 def context(self):
920 920 self.set_mode(self.valid_modes[1])
921 921
922 922 def verbose(self):
923 923 self.set_mode(self.valid_modes[2])
924 924
925 925 def minimal(self):
926 926 self.set_mode(self.valid_modes[3])
927 927
928 928
929 929 #----------------------------------------------------------------------------
930 930 class AutoFormattedTB(FormattedTB):
931 931 """A traceback printer which can be called on the fly.
932 932
933 933 It will find out about exceptions by itself.
934 934
935 935 A brief example::
936 936
937 937 AutoTB = AutoFormattedTB(mode = 'Verbose',color_scheme='Linux')
938 938 try:
939 939 ...
940 940 except:
941 941 AutoTB() # or AutoTB(out=logfile) where logfile is an open file object
942 942 """
943 943
944 944 def __call__(self, etype=None, evalue=None, etb=None,
945 945 out=None, tb_offset=None):
946 946 """Print out a formatted exception traceback.
947 947
948 948 Optional arguments:
949 949 - out: an open file-like object to direct output to.
950 950
951 951 - tb_offset: the number of frames to skip over in the stack, on a
952 952 per-call basis (this overrides temporarily the instance's tb_offset
953 953 given at initialization time. """
954 954
955 955 if out is None:
956 956 out = self.ostream
957 957 out.flush()
958 958 out.write(self.text(etype, evalue, etb, tb_offset))
959 959 out.write('\n')
960 960 out.flush()
961 961 # FIXME: we should remove the auto pdb behavior from here and leave
962 962 # that to the clients.
963 963 try:
964 964 self.debugger()
965 965 except KeyboardInterrupt:
966 966 print("\nKeyboardInterrupt")
967 967
968 968 def structured_traceback(self, etype=None, value=None, tb=None,
969 969 tb_offset=None, number_of_lines_of_context=5):
970 970 if etype is None:
971 971 etype, value, tb = sys.exc_info()
972 972 if isinstance(tb, tuple):
973 973 # tb is a tuple if this is a chained exception.
974 974 self.tb = tb[0]
975 975 else:
976 976 self.tb = tb
977 977 return FormattedTB.structured_traceback(
978 978 self, etype, value, tb, tb_offset, number_of_lines_of_context)
979 979
980 980
981 981 #---------------------------------------------------------------------------
982 982
983 983 # A simple class to preserve Nathan's original functionality.
984 984 class ColorTB(FormattedTB):
985 985 """Shorthand to initialize a FormattedTB in Linux colors mode."""
986 986
987 987 def __init__(self, color_scheme='Linux', call_pdb=0, **kwargs):
988 988 FormattedTB.__init__(self, color_scheme=color_scheme,
989 989 call_pdb=call_pdb, **kwargs)
990 990
991 991
992 992 class SyntaxTB(ListTB):
993 993 """Extension which holds some state: the last exception value"""
994 994
995 995 def __init__(self, color_scheme='NoColor', parent=None, config=None):
996 996 ListTB.__init__(self, color_scheme, parent=parent, config=config)
997 997 self.last_syntax_error = None
998 998
999 999 def __call__(self, etype, value, elist):
1000 1000 self.last_syntax_error = value
1001 1001
1002 1002 ListTB.__call__(self, etype, value, elist)
1003 1003
1004 1004 def structured_traceback(self, etype, value, elist, tb_offset=None,
1005 1005 context=5):
1006 1006 # If the source file has been edited, the line in the syntax error can
1007 1007 # be wrong (retrieved from an outdated cache). This replaces it with
1008 1008 # the current value.
1009 1009 if isinstance(value, SyntaxError) \
1010 1010 and isinstance(value.filename, str) \
1011 1011 and isinstance(value.lineno, int):
1012 1012 linecache.checkcache(value.filename)
1013 1013 newtext = linecache.getline(value.filename, value.lineno)
1014 1014 if newtext:
1015 1015 value.text = newtext
1016 1016 self.last_syntax_error = value
1017 1017 return super(SyntaxTB, self).structured_traceback(etype, value, elist,
1018 1018 tb_offset=tb_offset, context=context)
1019 1019
1020 1020 def clear_err_state(self):
1021 1021 """Return the current error state and clear it"""
1022 1022 e = self.last_syntax_error
1023 1023 self.last_syntax_error = None
1024 1024 return e
1025 1025
1026 1026 def stb2text(self, stb):
1027 1027 """Convert a structured traceback (a list) to a string."""
1028 1028 return ''.join(stb)
1029 1029
1030 1030
1031 1031 # some internal-use functions
1032 1032 def text_repr(value):
1033 1033 """Hopefully pretty robust repr equivalent."""
1034 1034 # this is pretty horrible but should always return *something*
1035 1035 try:
1036 1036 return pydoc.text.repr(value)
1037 1037 except KeyboardInterrupt:
1038 1038 raise
1039 1039 except:
1040 1040 try:
1041 1041 return repr(value)
1042 1042 except KeyboardInterrupt:
1043 1043 raise
1044 1044 except:
1045 1045 try:
1046 1046 # all still in an except block so we catch
1047 1047 # getattr raising
1048 1048 name = getattr(value, '__name__', None)
1049 1049 if name:
1050 1050 # ick, recursion
1051 1051 return text_repr(name)
1052 1052 klass = getattr(value, '__class__', None)
1053 1053 if klass:
1054 1054 return '%s instance' % text_repr(klass)
1055 1055 except KeyboardInterrupt:
1056 1056 raise
1057 1057 except:
1058 1058 return 'UNRECOVERABLE REPR FAILURE'
1059 1059
1060 1060
1061 1061 def eqrepr(value, repr=text_repr):
1062 1062 return '=%s' % repr(value)
1063 1063
1064 1064
1065 1065 def nullrepr(value, repr=text_repr):
1066 1066 return ''
General Comments 0
You need to be logged in to leave comments. Login now