##// END OF EJS Templates
Further removal of string module from core.
Thomas Kluyver -
Show More
@@ -1,892 +1,891 b''
1 1 # -*- coding: utf-8 -*-
2 2 """Tools for inspecting Python objects.
3 3
4 4 Uses syntax highlighting for presenting the various information elements.
5 5
6 6 Similar in spirit to the inspect module, but all calls take a name argument to
7 7 reference the name under which an object is being read.
8 8 """
9 9
10 10 #*****************************************************************************
11 11 # Copyright (C) 2001-2004 Fernando Perez <fperez@colorado.edu>
12 12 #
13 13 # Distributed under the terms of the BSD License. The full license is in
14 14 # the file COPYING, distributed as part of this software.
15 15 #*****************************************************************************
16 16
17 17 __all__ = ['Inspector','InspectColors']
18 18
19 19 # stdlib modules
20 20 import __builtin__
21 21 import StringIO
22 22 import inspect
23 23 import linecache
24 24 import os
25 import string
26 25 import sys
27 26 import types
28 27 from collections import namedtuple
29 28 from itertools import izip_longest
30 29
31 30 # IPython's own
32 31 from IPython.core import page
33 32 from IPython.external.Itpl import itpl
34 33 from IPython.utils import PyColorize
35 34 import IPython.utils.io
36 35 from IPython.utils.text import indent
37 36 from IPython.utils.wildcard import list_namespace
38 37 from IPython.utils.coloransi import *
39 38
40 39 #****************************************************************************
41 40 # Builtin color schemes
42 41
43 42 Colors = TermColors # just a shorthand
44 43
45 44 # Build a few color schemes
46 45 NoColor = ColorScheme(
47 46 'NoColor',{
48 47 'header' : Colors.NoColor,
49 48 'normal' : Colors.NoColor # color off (usu. Colors.Normal)
50 49 } )
51 50
52 51 LinuxColors = ColorScheme(
53 52 'Linux',{
54 53 'header' : Colors.LightRed,
55 54 'normal' : Colors.Normal # color off (usu. Colors.Normal)
56 55 } )
57 56
58 57 LightBGColors = ColorScheme(
59 58 'LightBG',{
60 59 'header' : Colors.Red,
61 60 'normal' : Colors.Normal # color off (usu. Colors.Normal)
62 61 } )
63 62
64 63 # Build table of color schemes (needed by the parser)
65 64 InspectColors = ColorSchemeTable([NoColor,LinuxColors,LightBGColors],
66 65 'Linux')
67 66
68 67 #****************************************************************************
69 68 # Auxiliary functions and objects
70 69
71 70 # See the messaging spec for the definition of all these fields. This list
72 71 # effectively defines the order of display
73 72 info_fields = ['type_name', 'base_class', 'string_form', 'namespace',
74 73 'length', 'file', 'definition', 'docstring', 'source',
75 74 'init_definition', 'class_docstring', 'init_docstring',
76 75 'call_def', 'call_docstring',
77 76 # These won't be printed but will be used to determine how to
78 77 # format the object
79 78 'ismagic', 'isalias', 'argspec', 'found', 'name',
80 79 ]
81 80
82 81
83 82 def object_info(**kw):
84 83 """Make an object info dict with all fields present."""
85 84 infodict = dict(izip_longest(info_fields, [None]))
86 85 infodict.update(kw)
87 86 return infodict
88 87
89 88
90 89 def getdoc(obj):
91 90 """Stable wrapper around inspect.getdoc.
92 91
93 92 This can't crash because of attribute problems.
94 93
95 94 It also attempts to call a getdoc() method on the given object. This
96 95 allows objects which provide their docstrings via non-standard mechanisms
97 96 (like Pyro proxies) to still be inspected by ipython's ? system."""
98 97
99 98 ds = None # default return value
100 99 try:
101 100 ds = inspect.getdoc(obj)
102 101 except:
103 102 # Harden against an inspect failure, which can occur with
104 103 # SWIG-wrapped extensions.
105 104 pass
106 105 # Allow objects to offer customized documentation via a getdoc method:
107 106 try:
108 107 ds2 = obj.getdoc()
109 108 except:
110 109 pass
111 110 else:
112 111 # if we get extra info, we add it to the normal docstring.
113 112 if ds is None:
114 113 ds = ds2
115 114 else:
116 115 ds = '%s\n%s' % (ds,ds2)
117 116 return ds
118 117
119 118
120 119 def getsource(obj,is_binary=False):
121 120 """Wrapper around inspect.getsource.
122 121
123 122 This can be modified by other projects to provide customized source
124 123 extraction.
125 124
126 125 Inputs:
127 126
128 127 - obj: an object whose source code we will attempt to extract.
129 128
130 129 Optional inputs:
131 130
132 131 - is_binary: whether the object is known to come from a binary source.
133 132 This implementation will skip returning any output for binary objects, but
134 133 custom extractors may know how to meaningfully process them."""
135 134
136 135 if is_binary:
137 136 return None
138 137 else:
139 138 try:
140 139 src = inspect.getsource(obj)
141 140 except TypeError:
142 141 if hasattr(obj,'__class__'):
143 142 src = inspect.getsource(obj.__class__)
144 143 return src
145 144
146 145 def getargspec(obj):
147 146 """Get the names and default values of a function's arguments.
148 147
149 148 A tuple of four things is returned: (args, varargs, varkw, defaults).
150 149 'args' is a list of the argument names (it may contain nested lists).
151 150 'varargs' and 'varkw' are the names of the * and ** arguments or None.
152 151 'defaults' is an n-tuple of the default values of the last n arguments.
153 152
154 153 Modified version of inspect.getargspec from the Python Standard
155 154 Library."""
156 155
157 156 if inspect.isfunction(obj):
158 157 func_obj = obj
159 158 elif inspect.ismethod(obj):
160 159 func_obj = obj.im_func
161 160 elif hasattr(obj, '__call__'):
162 161 func_obj = obj.__call__
163 162 else:
164 163 raise TypeError('arg is not a Python function')
165 164 args, varargs, varkw = inspect.getargs(func_obj.func_code)
166 165 return args, varargs, varkw, func_obj.func_defaults
167 166
168 167
169 168 def format_argspec(argspec):
170 169 """Format argspect, convenience wrapper around inspect's.
171 170
172 171 This takes a dict instead of ordered arguments and calls
173 172 inspect.format_argspec with the arguments in the necessary order.
174 173 """
175 174 return inspect.formatargspec(argspec['args'], argspec['varargs'],
176 175 argspec['varkw'], argspec['defaults'])
177 176
178 177
179 178 def call_tip(oinfo, format_call=True):
180 179 """Extract call tip data from an oinfo dict.
181 180
182 181 Parameters
183 182 ----------
184 183 oinfo : dict
185 184
186 185 format_call : bool, optional
187 186 If True, the call line is formatted and returned as a string. If not, a
188 187 tuple of (name, argspec) is returned.
189 188
190 189 Returns
191 190 -------
192 191 call_info : None, str or (str, dict) tuple.
193 192 When format_call is True, the whole call information is formattted as a
194 193 single string. Otherwise, the object's name and its argspec dict are
195 194 returned. If no call information is available, None is returned.
196 195
197 196 docstring : str or None
198 197 The most relevant docstring for calling purposes is returned, if
199 198 available. The priority is: call docstring for callable instances, then
200 199 constructor docstring for classes, then main object's docstring otherwise
201 200 (regular functions).
202 201 """
203 202 # Get call definition
204 203 argspec = oinfo['argspec']
205 204 if argspec is None:
206 205 call_line = None
207 206 else:
208 207 # Callable objects will have 'self' as their first argument, prune
209 208 # it out if it's there for clarity (since users do *not* pass an
210 209 # extra first argument explicitly).
211 210 try:
212 211 has_self = argspec['args'][0] == 'self'
213 212 except (KeyError, IndexError):
214 213 pass
215 214 else:
216 215 if has_self:
217 216 argspec['args'] = argspec['args'][1:]
218 217
219 218 call_line = oinfo['name']+format_argspec(argspec)
220 219
221 220 # Now get docstring.
222 221 # The priority is: call docstring, constructor docstring, main one.
223 222 doc = oinfo['call_docstring']
224 223 if doc is None:
225 224 doc = oinfo['init_docstring']
226 225 if doc is None:
227 226 doc = oinfo['docstring']
228 227
229 228 return call_line, doc
230 229
231 230 #****************************************************************************
232 231 # Class definitions
233 232
234 233 class myStringIO(StringIO.StringIO):
235 234 """Adds a writeln method to normal StringIO."""
236 235 def writeln(self,*arg,**kw):
237 236 """Does a write() and then a write('\n')"""
238 237 self.write(*arg,**kw)
239 238 self.write('\n')
240 239
241 240
242 241 class Inspector:
243 242 def __init__(self, color_table=InspectColors,
244 243 code_color_table=PyColorize.ANSICodeColors,
245 244 scheme='NoColor',
246 245 str_detail_level=0):
247 246 self.color_table = color_table
248 247 self.parser = PyColorize.Parser(code_color_table,out='str')
249 248 self.format = self.parser.format
250 249 self.str_detail_level = str_detail_level
251 250 self.set_active_scheme(scheme)
252 251
253 252 def _getdef(self,obj,oname=''):
254 253 """Return the definition header for any callable object.
255 254
256 255 If any exception is generated, None is returned instead and the
257 256 exception is suppressed."""
258 257
259 258 try:
260 259 # We need a plain string here, NOT unicode!
261 260 hdef = oname + inspect.formatargspec(*getargspec(obj))
262 261 return hdef.encode('ascii')
263 262 except:
264 263 return None
265 264
266 265 def __head(self,h):
267 266 """Return a header string with proper colors."""
268 267 return '%s%s%s' % (self.color_table.active_colors.header,h,
269 268 self.color_table.active_colors.normal)
270 269
271 270 def set_active_scheme(self,scheme):
272 271 self.color_table.set_active_scheme(scheme)
273 272 self.parser.color_table.set_active_scheme(scheme)
274 273
275 274 def noinfo(self,msg,oname):
276 275 """Generic message when no information is found."""
277 276 print 'No %s found' % msg,
278 277 if oname:
279 278 print 'for %s' % oname
280 279 else:
281 280 print
282 281
283 282 def pdef(self,obj,oname=''):
284 283 """Print the definition header for any callable object.
285 284
286 285 If the object is a class, print the constructor information."""
287 286
288 287 if not callable(obj):
289 288 print 'Object is not callable.'
290 289 return
291 290
292 291 header = ''
293 292
294 293 if inspect.isclass(obj):
295 294 header = self.__head('Class constructor information:\n')
296 295 obj = obj.__init__
297 296 elif type(obj) is types.InstanceType:
298 297 obj = obj.__call__
299 298
300 299 output = self._getdef(obj,oname)
301 300 if output is None:
302 301 self.noinfo('definition header',oname)
303 302 else:
304 303 print >>IPython.utils.io.Term.cout, header,self.format(output),
305 304
306 305 def pdoc(self,obj,oname='',formatter = None):
307 306 """Print the docstring for any object.
308 307
309 308 Optional:
310 309 -formatter: a function to run the docstring through for specially
311 310 formatted docstrings."""
312 311
313 312 head = self.__head # so that itpl can find it even if private
314 313 ds = getdoc(obj)
315 314 if formatter:
316 315 ds = formatter(ds)
317 316 if inspect.isclass(obj):
318 317 init_ds = getdoc(obj.__init__)
319 318 output = itpl('$head("Class Docstring:")\n'
320 319 '$indent(ds)\n'
321 320 '$head("Constructor Docstring"):\n'
322 321 '$indent(init_ds)')
323 322 elif (type(obj) is types.InstanceType or isinstance(obj,object)) \
324 323 and hasattr(obj,'__call__'):
325 324 call_ds = getdoc(obj.__call__)
326 325 if call_ds:
327 326 output = itpl('$head("Class Docstring:")\n$indent(ds)\n'
328 327 '$head("Calling Docstring:")\n$indent(call_ds)')
329 328 else:
330 329 output = ds
331 330 else:
332 331 output = ds
333 332 if output is None:
334 333 self.noinfo('documentation',oname)
335 334 return
336 335 page.page(output)
337 336
338 337 def psource(self,obj,oname=''):
339 338 """Print the source code for an object."""
340 339
341 340 # Flush the source cache because inspect can return out-of-date source
342 341 linecache.checkcache()
343 342 try:
344 343 src = getsource(obj)
345 344 except:
346 345 self.noinfo('source',oname)
347 346 else:
348 347 page.page(self.format(src))
349 348
350 349 def pfile(self,obj,oname=''):
351 350 """Show the whole file where an object was defined."""
352 351
353 352 try:
354 353 try:
355 354 lineno = inspect.getsourcelines(obj)[1]
356 355 except TypeError:
357 356 # For instances, try the class object like getsource() does
358 357 if hasattr(obj,'__class__'):
359 358 lineno = inspect.getsourcelines(obj.__class__)[1]
360 359 # Adjust the inspected object so getabsfile() below works
361 360 obj = obj.__class__
362 361 except:
363 362 self.noinfo('file',oname)
364 363 return
365 364
366 365 # We only reach this point if object was successfully queried
367 366
368 367 # run contents of file through pager starting at line
369 368 # where the object is defined
370 369 ofile = inspect.getabsfile(obj)
371 370
372 371 if (ofile.endswith('.so') or ofile.endswith('.dll')):
373 372 print 'File %r is binary, not printing.' % ofile
374 373 elif not os.path.isfile(ofile):
375 374 print 'File %r does not exist, not printing.' % ofile
376 375 else:
377 376 # Print only text files, not extension binaries. Note that
378 377 # getsourcelines returns lineno with 1-offset and page() uses
379 378 # 0-offset, so we must adjust.
380 379 page.page(self.format(open(ofile).read()),lineno-1)
381 380
382 381 def pinfo(self,obj,oname='',formatter=None,info=None,detail_level=0):
383 382 """Show detailed information about an object.
384 383
385 384 Optional arguments:
386 385
387 386 - oname: name of the variable pointing to the object.
388 387
389 388 - formatter: special formatter for docstrings (see pdoc)
390 389
391 390 - info: a structure with some information fields which may have been
392 391 precomputed already.
393 392
394 393 - detail_level: if set to 1, more information is given.
395 394 """
396 395
397 396 obj_type = type(obj)
398 397
399 398 header = self.__head
400 399 if info is None:
401 400 ismagic = 0
402 401 isalias = 0
403 402 ospace = ''
404 403 else:
405 404 ismagic = info.ismagic
406 405 isalias = info.isalias
407 406 ospace = info.namespace
408 407 # Get docstring, special-casing aliases:
409 408 if isalias:
410 409 if not callable(obj):
411 410 try:
412 411 ds = "Alias to the system command:\n %s" % obj[1]
413 412 except:
414 413 ds = "Alias: " + str(obj)
415 414 else:
416 415 ds = "Alias to " + str(obj)
417 416 if obj.__doc__:
418 417 ds += "\nDocstring:\n" + obj.__doc__
419 418 else:
420 419 ds = getdoc(obj)
421 420 if ds is None:
422 421 ds = '<no docstring>'
423 422 if formatter is not None:
424 423 ds = formatter(ds)
425 424
426 425 # store output in a list which gets joined with \n at the end.
427 426 out = myStringIO()
428 427
429 428 string_max = 200 # max size of strings to show (snipped if longer)
430 429 shalf = int((string_max -5)/2)
431 430
432 431 if ismagic:
433 432 obj_type_name = 'Magic function'
434 433 elif isalias:
435 434 obj_type_name = 'System alias'
436 435 else:
437 436 obj_type_name = obj_type.__name__
438 437 out.writeln(header('Type:\t\t')+obj_type_name)
439 438
440 439 try:
441 440 bclass = obj.__class__
442 441 out.writeln(header('Base Class:\t')+str(bclass))
443 442 except: pass
444 443
445 444 # String form, but snip if too long in ? form (full in ??)
446 445 if detail_level >= self.str_detail_level:
447 446 try:
448 447 ostr = str(obj)
449 448 str_head = 'String Form:'
450 449 if not detail_level and len(ostr)>string_max:
451 450 ostr = ostr[:shalf] + ' <...> ' + ostr[-shalf:]
452 451 ostr = ("\n" + " " * len(str_head.expandtabs())).\
453 join(map(string.strip,ostr.split("\n")))
452 join(q.strip() for q in ostr.split("\n"))
454 453 if ostr.find('\n') > -1:
455 454 # Print multi-line strings starting at the next line.
456 455 str_sep = '\n'
457 456 else:
458 457 str_sep = '\t'
459 458 out.writeln("%s%s%s" % (header(str_head),str_sep,ostr))
460 459 except:
461 460 pass
462 461
463 462 if ospace:
464 463 out.writeln(header('Namespace:\t')+ospace)
465 464
466 465 # Length (for strings and lists)
467 466 try:
468 467 length = str(len(obj))
469 468 out.writeln(header('Length:\t\t')+length)
470 469 except: pass
471 470
472 471 # Filename where object was defined
473 472 binary_file = False
474 473 try:
475 474 try:
476 475 fname = inspect.getabsfile(obj)
477 476 except TypeError:
478 477 # For an instance, the file that matters is where its class was
479 478 # declared.
480 479 if hasattr(obj,'__class__'):
481 480 fname = inspect.getabsfile(obj.__class__)
482 481 if fname.endswith('<string>'):
483 482 fname = 'Dynamically generated function. No source code available.'
484 483 if (fname.endswith('.so') or fname.endswith('.dll')):
485 484 binary_file = True
486 485 out.writeln(header('File:\t\t')+fname)
487 486 except:
488 487 # if anything goes wrong, we don't want to show source, so it's as
489 488 # if the file was binary
490 489 binary_file = True
491 490
492 491 # reconstruct the function definition and print it:
493 492 defln = self._getdef(obj,oname)
494 493 if defln:
495 494 out.write(header('Definition:\t')+self.format(defln))
496 495
497 496 # Docstrings only in detail 0 mode, since source contains them (we
498 497 # avoid repetitions). If source fails, we add them back, see below.
499 498 if ds and detail_level == 0:
500 499 out.writeln(header('Docstring:\n') + indent(ds))
501 500
502 501 # Original source code for any callable
503 502 if detail_level:
504 503 # Flush the source cache because inspect can return out-of-date
505 504 # source
506 505 linecache.checkcache()
507 506 source_success = False
508 507 try:
509 508 try:
510 509 src = getsource(obj,binary_file)
511 510 except TypeError:
512 511 if hasattr(obj,'__class__'):
513 512 src = getsource(obj.__class__,binary_file)
514 513 if src is not None:
515 514 source = self.format(src)
516 515 out.write(header('Source:\n')+source.rstrip())
517 516 source_success = True
518 517 except Exception, msg:
519 518 pass
520 519
521 520 if ds and not source_success:
522 521 out.writeln(header('Docstring [source file open failed]:\n')
523 522 + indent(ds))
524 523
525 524 # Constructor docstring for classes
526 525 if inspect.isclass(obj):
527 526 # reconstruct the function definition and print it:
528 527 try:
529 528 obj_init = obj.__init__
530 529 except AttributeError:
531 530 init_def = init_ds = None
532 531 else:
533 532 init_def = self._getdef(obj_init,oname)
534 533 init_ds = getdoc(obj_init)
535 534 # Skip Python's auto-generated docstrings
536 535 if init_ds and \
537 536 init_ds.startswith('x.__init__(...) initializes'):
538 537 init_ds = None
539 538
540 539 if init_def or init_ds:
541 540 out.writeln(header('\nConstructor information:'))
542 541 if init_def:
543 542 out.write(header('Definition:\t')+ self.format(init_def))
544 543 if init_ds:
545 544 out.writeln(header('Docstring:\n') + indent(init_ds))
546 545 # and class docstring for instances:
547 546 elif obj_type is types.InstanceType or \
548 547 isinstance(obj,object):
549 548
550 549 # First, check whether the instance docstring is identical to the
551 550 # class one, and print it separately if they don't coincide. In
552 551 # most cases they will, but it's nice to print all the info for
553 552 # objects which use instance-customized docstrings.
554 553 if ds:
555 554 try:
556 555 cls = getattr(obj,'__class__')
557 556 except:
558 557 class_ds = None
559 558 else:
560 559 class_ds = getdoc(cls)
561 560 # Skip Python's auto-generated docstrings
562 561 if class_ds and \
563 562 (class_ds.startswith('function(code, globals[,') or \
564 563 class_ds.startswith('instancemethod(function, instance,') or \
565 564 class_ds.startswith('module(name[,') ):
566 565 class_ds = None
567 566 if class_ds and ds != class_ds:
568 567 out.writeln(header('Class Docstring:\n') +
569 568 indent(class_ds))
570 569
571 570 # Next, try to show constructor docstrings
572 571 try:
573 572 init_ds = getdoc(obj.__init__)
574 573 # Skip Python's auto-generated docstrings
575 574 if init_ds and \
576 575 init_ds.startswith('x.__init__(...) initializes'):
577 576 init_ds = None
578 577 except AttributeError:
579 578 init_ds = None
580 579 if init_ds:
581 580 out.writeln(header('Constructor Docstring:\n') +
582 581 indent(init_ds))
583 582
584 583 # Call form docstring for callable instances
585 584 if hasattr(obj,'__call__'):
586 585 #out.writeln(header('Callable:\t')+'Yes')
587 586 call_def = self._getdef(obj.__call__,oname)
588 587 #if call_def is None:
589 588 # out.writeln(header('Call def:\t')+
590 589 # 'Calling definition not available.')
591 590 if call_def is not None:
592 591 out.writeln(header('Call def:\t')+self.format(call_def))
593 592 call_ds = getdoc(obj.__call__)
594 593 # Skip Python's auto-generated docstrings
595 594 if call_ds and call_ds.startswith('x.__call__(...) <==> x(...)'):
596 595 call_ds = None
597 596 if call_ds:
598 597 out.writeln(header('Call docstring:\n') + indent(call_ds))
599 598
600 599 # Finally send to printer/pager
601 600 output = out.getvalue()
602 601 if output:
603 602 page.page(output)
604 603 # end pinfo
605 604
606 605 def info(self, obj, oname='', formatter=None, info=None, detail_level=0):
607 606 """Compute a dict with detailed information about an object.
608 607
609 608 Optional arguments:
610 609
611 610 - oname: name of the variable pointing to the object.
612 611
613 612 - formatter: special formatter for docstrings (see pdoc)
614 613
615 614 - info: a structure with some information fields which may have been
616 615 precomputed already.
617 616
618 617 - detail_level: if set to 1, more information is given.
619 618 """
620 619
621 620 obj_type = type(obj)
622 621
623 622 header = self.__head
624 623 if info is None:
625 624 ismagic = 0
626 625 isalias = 0
627 626 ospace = ''
628 627 else:
629 628 ismagic = info.ismagic
630 629 isalias = info.isalias
631 630 ospace = info.namespace
632 631
633 632 # Get docstring, special-casing aliases:
634 633 if isalias:
635 634 if not callable(obj):
636 635 try:
637 636 ds = "Alias to the system command:\n %s" % obj[1]
638 637 except:
639 638 ds = "Alias: " + str(obj)
640 639 else:
641 640 ds = "Alias to " + str(obj)
642 641 if obj.__doc__:
643 642 ds += "\nDocstring:\n" + obj.__doc__
644 643 else:
645 644 ds = getdoc(obj)
646 645 if ds is None:
647 646 ds = '<no docstring>'
648 647 if formatter is not None:
649 648 ds = formatter(ds)
650 649
651 650 # store output in a dict, we initialize it here and fill it as we go
652 651 out = dict(name=oname, found=True, isalias=isalias, ismagic=ismagic)
653 652
654 653 string_max = 200 # max size of strings to show (snipped if longer)
655 654 shalf = int((string_max -5)/2)
656 655
657 656 if ismagic:
658 657 obj_type_name = 'Magic function'
659 658 elif isalias:
660 659 obj_type_name = 'System alias'
661 660 else:
662 661 obj_type_name = obj_type.__name__
663 662 out['type_name'] = obj_type_name
664 663
665 664 try:
666 665 bclass = obj.__class__
667 666 out['base_class'] = str(bclass)
668 667 except: pass
669 668
670 669 # String form, but snip if too long in ? form (full in ??)
671 670 if detail_level >= self.str_detail_level:
672 671 try:
673 672 ostr = str(obj)
674 673 str_head = 'string_form'
675 674 if not detail_level and len(ostr)>string_max:
676 675 ostr = ostr[:shalf] + ' <...> ' + ostr[-shalf:]
677 676 ostr = ("\n" + " " * len(str_head.expandtabs())).\
678 join(map(string.strip,ostr.split("\n")))
677 join(q.strip() for q in ostr.split("\n"))
679 678 if ostr.find('\n') > -1:
680 679 # Print multi-line strings starting at the next line.
681 680 str_sep = '\n'
682 681 else:
683 682 str_sep = '\t'
684 683 out[str_head] = ostr
685 684 except:
686 685 pass
687 686
688 687 if ospace:
689 688 out['namespace'] = ospace
690 689
691 690 # Length (for strings and lists)
692 691 try:
693 692 out['length'] = str(len(obj))
694 693 except: pass
695 694
696 695 # Filename where object was defined
697 696 binary_file = False
698 697 try:
699 698 try:
700 699 fname = inspect.getabsfile(obj)
701 700 except TypeError:
702 701 # For an instance, the file that matters is where its class was
703 702 # declared.
704 703 if hasattr(obj,'__class__'):
705 704 fname = inspect.getabsfile(obj.__class__)
706 705 if fname.endswith('<string>'):
707 706 fname = 'Dynamically generated function. No source code available.'
708 707 if (fname.endswith('.so') or fname.endswith('.dll')):
709 708 binary_file = True
710 709 out['file'] = fname
711 710 except:
712 711 # if anything goes wrong, we don't want to show source, so it's as
713 712 # if the file was binary
714 713 binary_file = True
715 714
716 715 # reconstruct the function definition and print it:
717 716 defln = self._getdef(obj, oname)
718 717 if defln:
719 718 out['definition'] = self.format(defln)
720 719
721 720 # Docstrings only in detail 0 mode, since source contains them (we
722 721 # avoid repetitions). If source fails, we add them back, see below.
723 722 if ds and detail_level == 0:
724 723 out['docstring'] = ds
725 724
726 725 # Original source code for any callable
727 726 if detail_level:
728 727 # Flush the source cache because inspect can return out-of-date
729 728 # source
730 729 linecache.checkcache()
731 730 source_success = False
732 731 try:
733 732 try:
734 733 src = getsource(obj,binary_file)
735 734 except TypeError:
736 735 if hasattr(obj,'__class__'):
737 736 src = getsource(obj.__class__,binary_file)
738 737 if src is not None:
739 738 source = self.format(src)
740 739 out['source'] = source.rstrip()
741 740 source_success = True
742 741 except Exception, msg:
743 742 pass
744 743
745 744 # Constructor docstring for classes
746 745 if inspect.isclass(obj):
747 746 # reconstruct the function definition and print it:
748 747 try:
749 748 obj_init = obj.__init__
750 749 except AttributeError:
751 750 init_def = init_ds = None
752 751 else:
753 752 init_def = self._getdef(obj_init,oname)
754 753 init_ds = getdoc(obj_init)
755 754 # Skip Python's auto-generated docstrings
756 755 if init_ds and \
757 756 init_ds.startswith('x.__init__(...) initializes'):
758 757 init_ds = None
759 758
760 759 if init_def or init_ds:
761 760 if init_def:
762 761 out['init_definition'] = self.format(init_def)
763 762 if init_ds:
764 763 out['init_docstring'] = init_ds
765 764
766 765 # and class docstring for instances:
767 766 elif obj_type is types.InstanceType or \
768 767 isinstance(obj, object):
769 768 # First, check whether the instance docstring is identical to the
770 769 # class one, and print it separately if they don't coincide. In
771 770 # most cases they will, but it's nice to print all the info for
772 771 # objects which use instance-customized docstrings.
773 772 if ds:
774 773 try:
775 774 cls = getattr(obj,'__class__')
776 775 except:
777 776 class_ds = None
778 777 else:
779 778 class_ds = getdoc(cls)
780 779 # Skip Python's auto-generated docstrings
781 780 if class_ds and \
782 781 (class_ds.startswith('function(code, globals[,') or \
783 782 class_ds.startswith('instancemethod(function, instance,') or \
784 783 class_ds.startswith('module(name[,') ):
785 784 class_ds = None
786 785 if class_ds and ds != class_ds:
787 786 out['class_docstring'] = class_ds
788 787
789 788 # Next, try to show constructor docstrings
790 789 try:
791 790 init_ds = getdoc(obj.__init__)
792 791 # Skip Python's auto-generated docstrings
793 792 if init_ds and \
794 793 init_ds.startswith('x.__init__(...) initializes'):
795 794 init_ds = None
796 795 except AttributeError:
797 796 init_ds = None
798 797 if init_ds:
799 798 out['init_docstring'] = init_ds
800 799
801 800 # Call form docstring for callable instances
802 801 if hasattr(obj, '__call__'):
803 802 call_def = self._getdef(obj.__call__, oname)
804 803 if call_def is not None:
805 804 out['call_def'] = self.format(call_def)
806 805 call_ds = getdoc(obj.__call__)
807 806 # Skip Python's auto-generated docstrings
808 807 if call_ds and call_ds.startswith('x.__call__(...) <==> x(...)'):
809 808 call_ds = None
810 809 if call_ds:
811 810 out['call_docstring'] = call_ds
812 811
813 812 # Compute the object's argspec as a callable. The key is to decide
814 813 # whether to pull it from the object itself, from its __init__ or
815 814 # from its __call__ method.
816 815
817 816 if inspect.isclass(obj):
818 817 callable_obj = obj.__init__
819 818 elif callable(obj):
820 819 callable_obj = obj
821 820 else:
822 821 callable_obj = None
823 822
824 823 if callable_obj:
825 824 try:
826 825 args, varargs, varkw, defaults = getargspec(callable_obj)
827 826 except (TypeError, AttributeError):
828 827 # For extensions/builtins we can't retrieve the argspec
829 828 pass
830 829 else:
831 830 out['argspec'] = dict(args=args, varargs=varargs,
832 831 varkw=varkw, defaults=defaults)
833 832
834 833 return object_info(**out)
835 834
836 835
837 836 def psearch(self,pattern,ns_table,ns_search=[],
838 837 ignore_case=False,show_all=False):
839 838 """Search namespaces with wildcards for objects.
840 839
841 840 Arguments:
842 841
843 842 - pattern: string containing shell-like wildcards to use in namespace
844 843 searches and optionally a type specification to narrow the search to
845 844 objects of that type.
846 845
847 846 - ns_table: dict of name->namespaces for search.
848 847
849 848 Optional arguments:
850 849
851 850 - ns_search: list of namespace names to include in search.
852 851
853 852 - ignore_case(False): make the search case-insensitive.
854 853
855 854 - show_all(False): show all names, including those starting with
856 855 underscores.
857 856 """
858 857 #print 'ps pattern:<%r>' % pattern # dbg
859 858
860 859 # defaults
861 860 type_pattern = 'all'
862 861 filter = ''
863 862
864 863 cmds = pattern.split()
865 864 len_cmds = len(cmds)
866 865 if len_cmds == 1:
867 866 # Only filter pattern given
868 867 filter = cmds[0]
869 868 elif len_cmds == 2:
870 869 # Both filter and type specified
871 870 filter,type_pattern = cmds
872 871 else:
873 872 raise ValueError('invalid argument string for psearch: <%s>' %
874 873 pattern)
875 874
876 875 # filter search namespaces
877 876 for name in ns_search:
878 877 if name not in ns_table:
879 878 raise ValueError('invalid namespace <%s>. Valid names: %s' %
880 879 (name,ns_table.keys()))
881 880
882 881 #print 'type_pattern:',type_pattern # dbg
883 882 search_result = []
884 883 for ns_name in ns_search:
885 884 ns = ns_table[ns_name]
886 885 tmp_res = list(list_namespace(ns,type_pattern,filter,
887 886 ignore_case=ignore_case,
888 887 show_all=show_all))
889 888 search_result.extend(tmp_res)
890 889 search_result.sort()
891 890
892 891 page.page('\n'.join(search_result))
@@ -1,1230 +1,1229 b''
1 1 # -*- coding: utf-8 -*-
2 2 """
3 3 ultratb.py -- Spice up your tracebacks!
4 4
5 5 * ColorTB
6 6 I've always found it a bit hard to visually parse tracebacks in Python. The
7 7 ColorTB class is a solution to that problem. It colors the different parts of a
8 8 traceback in a manner similar to what you would expect from a syntax-highlighting
9 9 text editor.
10 10
11 11 Installation instructions for ColorTB:
12 12 import sys,ultratb
13 13 sys.excepthook = ultratb.ColorTB()
14 14
15 15 * VerboseTB
16 16 I've also included a port of Ka-Ping Yee's "cgitb.py" that produces all kinds
17 17 of useful info when a traceback occurs. Ping originally had it spit out HTML
18 18 and intended it for CGI programmers, but why should they have all the fun? I
19 19 altered it to spit out colored text to the terminal. It's a bit overwhelming,
20 20 but kind of neat, and maybe useful for long-running programs that you believe
21 21 are bug-free. If a crash *does* occur in that type of program you want details.
22 22 Give it a shot--you'll love it or you'll hate it.
23 23
24 24 Note:
25 25
26 26 The Verbose mode prints the variables currently visible where the exception
27 27 happened (shortening their strings if too long). This can potentially be
28 28 very slow, if you happen to have a huge data structure whose string
29 29 representation is complex to compute. Your computer may appear to freeze for
30 30 a while with cpu usage at 100%. If this occurs, you can cancel the traceback
31 31 with Ctrl-C (maybe hitting it more than once).
32 32
33 33 If you encounter this kind of situation often, you may want to use the
34 34 Verbose_novars mode instead of the regular Verbose, which avoids formatting
35 35 variables (but otherwise includes the information and context given by
36 36 Verbose).
37 37
38 38
39 39 Installation instructions for ColorTB:
40 40 import sys,ultratb
41 41 sys.excepthook = ultratb.VerboseTB()
42 42
43 43 Note: Much of the code in this module was lifted verbatim from the standard
44 44 library module 'traceback.py' and Ka-Ping Yee's 'cgitb.py'.
45 45
46 46 * Color schemes
47 47 The colors are defined in the class TBTools through the use of the
48 48 ColorSchemeTable class. Currently the following exist:
49 49
50 50 - NoColor: allows all of this module to be used in any terminal (the color
51 51 escapes are just dummy blank strings).
52 52
53 53 - Linux: is meant to look good in a terminal like the Linux console (black
54 54 or very dark background).
55 55
56 56 - LightBG: similar to Linux but swaps dark/light colors to be more readable
57 57 in light background terminals.
58 58
59 59 You can implement other color schemes easily, the syntax is fairly
60 60 self-explanatory. Please send back new schemes you develop to the author for
61 61 possible inclusion in future releases.
62 62 """
63 63
64 64 #*****************************************************************************
65 65 # Copyright (C) 2001 Nathaniel Gray <n8gray@caltech.edu>
66 66 # Copyright (C) 2001-2004 Fernando Perez <fperez@colorado.edu>
67 67 #
68 68 # Distributed under the terms of the BSD License. The full license is in
69 69 # the file COPYING, distributed as part of this software.
70 70 #*****************************************************************************
71 71
72 72 from __future__ import with_statement
73 73
74 74 import inspect
75 75 import keyword
76 76 import linecache
77 77 import os
78 78 import pydoc
79 79 import re
80 import string
81 80 import sys
82 81 import time
83 82 import tokenize
84 83 import traceback
85 84 import types
86 85
87 86 # For purposes of monkeypatching inspect to fix a bug in it.
88 87 from inspect import getsourcefile, getfile, getmodule,\
89 88 ismodule, isclass, ismethod, isfunction, istraceback, isframe, iscode
90 89
91 90 # IPython's own modules
92 91 # Modified pdb which doesn't damage IPython's readline handling
93 92 from IPython.core import debugger, ipapi
94 93 from IPython.core.display_trap import DisplayTrap
95 94 from IPython.core.excolors import exception_colors
96 95 from IPython.utils import PyColorize
97 96 from IPython.utils import io
98 97 from IPython.utils.data import uniq_stable
99 98 from IPython.utils.warn import info, error
100 99
101 100 # Globals
102 101 # amount of space to put line numbers before verbose tracebacks
103 102 INDENT_SIZE = 8
104 103
105 104 # Default color scheme. This is used, for example, by the traceback
106 105 # formatter. When running in an actual IPython instance, the user's rc.colors
107 106 # value is used, but havinga module global makes this functionality available
108 107 # to users of ultratb who are NOT running inside ipython.
109 108 DEFAULT_SCHEME = 'NoColor'
110 109
111 110 #---------------------------------------------------------------------------
112 111 # Code begins
113 112
114 113 # Utility functions
115 114 def inspect_error():
116 115 """Print a message about internal inspect errors.
117 116
118 117 These are unfortunately quite common."""
119 118
120 119 error('Internal Python error in the inspect module.\n'
121 120 'Below is the traceback from this internal error.\n')
122 121
123 122
124 123 def findsource(object):
125 124 """Return the entire source file and starting line number for an object.
126 125
127 126 The argument may be a module, class, method, function, traceback, frame,
128 127 or code object. The source code is returned as a list of all the lines
129 128 in the file and the line number indexes a line in that list. An IOError
130 129 is raised if the source code cannot be retrieved.
131 130
132 131 FIXED version with which we monkeypatch the stdlib to work around a bug."""
133 132
134 133 file = getsourcefile(object) or getfile(object)
135 134 # If the object is a frame, then trying to get the globals dict from its
136 135 # module won't work. Instead, the frame object itself has the globals
137 136 # dictionary.
138 137 globals_dict = None
139 138 if inspect.isframe(object):
140 139 # XXX: can this ever be false?
141 140 globals_dict = object.f_globals
142 141 else:
143 142 module = getmodule(object, file)
144 143 if module:
145 144 globals_dict = module.__dict__
146 145 lines = linecache.getlines(file, globals_dict)
147 146 if not lines:
148 147 raise IOError('could not get source code')
149 148
150 149 if ismodule(object):
151 150 return lines, 0
152 151
153 152 if isclass(object):
154 153 name = object.__name__
155 154 pat = re.compile(r'^(\s*)class\s*' + name + r'\b')
156 155 # make some effort to find the best matching class definition:
157 156 # use the one with the least indentation, which is the one
158 157 # that's most probably not inside a function definition.
159 158 candidates = []
160 159 for i in range(len(lines)):
161 160 match = pat.match(lines[i])
162 161 if match:
163 162 # if it's at toplevel, it's already the best one
164 163 if lines[i][0] == 'c':
165 164 return lines, i
166 165 # else add whitespace to candidate list
167 166 candidates.append((match.group(1), i))
168 167 if candidates:
169 168 # this will sort by whitespace, and by line number,
170 169 # less whitespace first
171 170 candidates.sort()
172 171 return lines, candidates[0][1]
173 172 else:
174 173 raise IOError('could not find class definition')
175 174
176 175 if ismethod(object):
177 176 object = object.im_func
178 177 if isfunction(object):
179 178 object = object.func_code
180 179 if istraceback(object):
181 180 object = object.tb_frame
182 181 if isframe(object):
183 182 object = object.f_code
184 183 if iscode(object):
185 184 if not hasattr(object, 'co_firstlineno'):
186 185 raise IOError('could not find function definition')
187 186 pat = re.compile(r'^(\s*def\s)|(.*(?<!\w)lambda(:|\s))|^(\s*@)')
188 187 pmatch = pat.match
189 188 # fperez - fix: sometimes, co_firstlineno can give a number larger than
190 189 # the length of lines, which causes an error. Safeguard against that.
191 190 lnum = min(object.co_firstlineno,len(lines))-1
192 191 while lnum > 0:
193 192 if pmatch(lines[lnum]): break
194 193 lnum -= 1
195 194
196 195 return lines, lnum
197 196 raise IOError('could not find code object')
198 197
199 198 # Monkeypatch inspect to apply our bugfix. This code only works with py25
200 199 if sys.version_info[:2] >= (2,5):
201 200 inspect.findsource = findsource
202 201
203 202 def fix_frame_records_filenames(records):
204 203 """Try to fix the filenames in each record from inspect.getinnerframes().
205 204
206 205 Particularly, modules loaded from within zip files have useless filenames
207 206 attached to their code object, and inspect.getinnerframes() just uses it.
208 207 """
209 208 fixed_records = []
210 209 for frame, filename, line_no, func_name, lines, index in records:
211 210 # Look inside the frame's globals dictionary for __file__, which should
212 211 # be better.
213 212 better_fn = frame.f_globals.get('__file__', None)
214 213 if isinstance(better_fn, str):
215 214 # Check the type just in case someone did something weird with
216 215 # __file__. It might also be None if the error occurred during
217 216 # import.
218 217 filename = better_fn
219 218 fixed_records.append((frame, filename, line_no, func_name, lines, index))
220 219 return fixed_records
221 220
222 221
223 222 def _fixed_getinnerframes(etb, context=1,tb_offset=0):
224 223 import linecache
225 224 LNUM_POS, LINES_POS, INDEX_POS = 2, 4, 5
226 225
227 226 records = fix_frame_records_filenames(inspect.getinnerframes(etb, context))
228 227
229 228 # If the error is at the console, don't build any context, since it would
230 229 # otherwise produce 5 blank lines printed out (there is no file at the
231 230 # console)
232 231 rec_check = records[tb_offset:]
233 232 try:
234 233 rname = rec_check[0][1]
235 234 if rname == '<ipython console>' or rname.endswith('<string>'):
236 235 return rec_check
237 236 except IndexError:
238 237 pass
239 238
240 239 aux = traceback.extract_tb(etb)
241 240 assert len(records) == len(aux)
242 241 for i, (file, lnum, _, _) in zip(range(len(records)), aux):
243 242 maybeStart = lnum-1 - context//2
244 243 start = max(maybeStart, 0)
245 244 end = start + context
246 245 lines = linecache.getlines(file)[start:end]
247 246 # pad with empty lines if necessary
248 247 if maybeStart < 0:
249 248 lines = (['\n'] * -maybeStart) + lines
250 249 if len(lines) < context:
251 250 lines += ['\n'] * (context - len(lines))
252 251 buf = list(records[i])
253 252 buf[LNUM_POS] = lnum
254 253 buf[INDEX_POS] = lnum - 1 - start
255 254 buf[LINES_POS] = lines
256 255 records[i] = tuple(buf)
257 256 return records[tb_offset:]
258 257
259 258 # Helper function -- largely belongs to VerboseTB, but we need the same
260 259 # functionality to produce a pseudo verbose TB for SyntaxErrors, so that they
261 260 # can be recognized properly by ipython.el's py-traceback-line-re
262 261 # (SyntaxErrors have to be treated specially because they have no traceback)
263 262
264 263 _parser = PyColorize.Parser()
265 264
266 265 def _format_traceback_lines(lnum, index, lines, Colors, lvals=None,scheme=None):
267 266 numbers_width = INDENT_SIZE - 1
268 267 res = []
269 268 i = lnum - index
270 269
271 270 # This lets us get fully syntax-highlighted tracebacks.
272 271 if scheme is None:
273 272 ipinst = ipapi.get()
274 273 if ipinst is not None:
275 274 scheme = ipinst.colors
276 275 else:
277 276 scheme = DEFAULT_SCHEME
278 277
279 278 _line_format = _parser.format2
280 279
281 280 for line in lines:
282 281 new_line, err = _line_format(line,'str',scheme)
283 282 if not err: line = new_line
284 283
285 284 if i == lnum:
286 285 # This is the line with the error
287 286 pad = numbers_width - len(str(i))
288 287 if pad >= 3:
289 288 marker = '-'*(pad-3) + '-> '
290 289 elif pad == 2:
291 290 marker = '> '
292 291 elif pad == 1:
293 292 marker = '>'
294 293 else:
295 294 marker = ''
296 295 num = marker + str(i)
297 296 line = '%s%s%s %s%s' %(Colors.linenoEm, num,
298 297 Colors.line, line, Colors.Normal)
299 298 else:
300 299 num = '%*s' % (numbers_width,i)
301 300 line = '%s%s%s %s' %(Colors.lineno, num,
302 301 Colors.Normal, line)
303 302
304 303 res.append(line)
305 304 if lvals and i == lnum:
306 305 res.append(lvals + '\n')
307 306 i = i + 1
308 307 return res
309 308
310 309
311 310 #---------------------------------------------------------------------------
312 311 # Module classes
313 312 class TBTools(object):
314 313 """Basic tools used by all traceback printer classes."""
315 314
316 315 # Number of frames to skip when reporting tracebacks
317 316 tb_offset = 0
318 317
319 318 def __init__(self, color_scheme='NoColor', call_pdb=False, ostream=None):
320 319 # Whether to call the interactive pdb debugger after printing
321 320 # tracebacks or not
322 321 self.call_pdb = call_pdb
323 322
324 323 # Output stream to write to. Note that we store the original value in
325 324 # a private attribute and then make the public ostream a property, so
326 325 # that we can delay accessing io.Term.cout until runtime. The way
327 326 # things are written now, the Term.cout object is dynamically managed
328 327 # so a reference to it should NEVER be stored statically. This
329 328 # property approach confines this detail to a single location, and all
330 329 # subclasses can simply access self.ostream for writing.
331 330 self._ostream = ostream
332 331
333 332 # Create color table
334 333 self.color_scheme_table = exception_colors()
335 334
336 335 self.set_colors(color_scheme)
337 336 self.old_scheme = color_scheme # save initial value for toggles
338 337
339 338 if call_pdb:
340 339 self.pdb = debugger.Pdb(self.color_scheme_table.active_scheme_name)
341 340 else:
342 341 self.pdb = None
343 342
344 343 def _get_ostream(self):
345 344 """Output stream that exceptions are written to.
346 345
347 346 Valid values are:
348 347
349 348 - None: the default, which means that IPython will dynamically resolve
350 349 to io.Term.cout. This ensures compatibility with most tools, including
351 350 Windows (where plain stdout doesn't recognize ANSI escapes).
352 351
353 352 - Any object with 'write' and 'flush' attributes.
354 353 """
355 354 return io.Term.cout if self._ostream is None else self._ostream
356 355
357 356 def _set_ostream(self, val):
358 357 assert val is None or (hasattr(val, 'write') and hasattr(val, 'flush'))
359 358 self._ostream = val
360 359
361 360 ostream = property(_get_ostream, _set_ostream)
362 361
363 362 def set_colors(self,*args,**kw):
364 363 """Shorthand access to the color table scheme selector method."""
365 364
366 365 # Set own color table
367 366 self.color_scheme_table.set_active_scheme(*args,**kw)
368 367 # for convenience, set Colors to the active scheme
369 368 self.Colors = self.color_scheme_table.active_colors
370 369 # Also set colors of debugger
371 370 if hasattr(self,'pdb') and self.pdb is not None:
372 371 self.pdb.set_colors(*args,**kw)
373 372
374 373 def color_toggle(self):
375 374 """Toggle between the currently active color scheme and NoColor."""
376 375
377 376 if self.color_scheme_table.active_scheme_name == 'NoColor':
378 377 self.color_scheme_table.set_active_scheme(self.old_scheme)
379 378 self.Colors = self.color_scheme_table.active_colors
380 379 else:
381 380 self.old_scheme = self.color_scheme_table.active_scheme_name
382 381 self.color_scheme_table.set_active_scheme('NoColor')
383 382 self.Colors = self.color_scheme_table.active_colors
384 383
385 384 def stb2text(self, stb):
386 385 """Convert a structured traceback (a list) to a string."""
387 386 return '\n'.join(stb)
388 387
389 388 def text(self, etype, value, tb, tb_offset=None, context=5):
390 389 """Return formatted traceback.
391 390
392 391 Subclasses may override this if they add extra arguments.
393 392 """
394 393 tb_list = self.structured_traceback(etype, value, tb,
395 394 tb_offset, context)
396 395 return self.stb2text(tb_list)
397 396
398 397 def structured_traceback(self, etype, evalue, tb, tb_offset=None,
399 398 context=5, mode=None):
400 399 """Return a list of traceback frames.
401 400
402 401 Must be implemented by each class.
403 402 """
404 403 raise NotImplementedError()
405 404
406 405
407 406 #---------------------------------------------------------------------------
408 407 class ListTB(TBTools):
409 408 """Print traceback information from a traceback list, with optional color.
410 409
411 410 Calling: requires 3 arguments:
412 411 (etype, evalue, elist)
413 412 as would be obtained by:
414 413 etype, evalue, tb = sys.exc_info()
415 414 if tb:
416 415 elist = traceback.extract_tb(tb)
417 416 else:
418 417 elist = None
419 418
420 419 It can thus be used by programs which need to process the traceback before
421 420 printing (such as console replacements based on the code module from the
422 421 standard library).
423 422
424 423 Because they are meant to be called without a full traceback (only a
425 424 list), instances of this class can't call the interactive pdb debugger."""
426 425
427 426 def __init__(self,color_scheme = 'NoColor', call_pdb=False, ostream=None):
428 427 TBTools.__init__(self, color_scheme=color_scheme, call_pdb=call_pdb,
429 428 ostream=ostream)
430 429
431 430 def __call__(self, etype, value, elist):
432 431 self.ostream.flush()
433 432 self.ostream.write(self.text(etype, value, elist))
434 433 self.ostream.write('\n')
435 434
436 435 def structured_traceback(self, etype, value, elist, tb_offset=None,
437 436 context=5):
438 437 """Return a color formatted string with the traceback info.
439 438
440 439 Parameters
441 440 ----------
442 441 etype : exception type
443 442 Type of the exception raised.
444 443
445 444 value : object
446 445 Data stored in the exception
447 446
448 447 elist : list
449 448 List of frames, see class docstring for details.
450 449
451 450 tb_offset : int, optional
452 451 Number of frames in the traceback to skip. If not given, the
453 452 instance value is used (set in constructor).
454 453
455 454 context : int, optional
456 455 Number of lines of context information to print.
457 456
458 457 Returns
459 458 -------
460 459 String with formatted exception.
461 460 """
462 461 tb_offset = self.tb_offset if tb_offset is None else tb_offset
463 462 Colors = self.Colors
464 463 out_list = []
465 464 if elist:
466 465
467 466 if tb_offset and len(elist) > tb_offset:
468 467 elist = elist[tb_offset:]
469 468
470 469 out_list.append('Traceback %s(most recent call last)%s:' %
471 470 (Colors.normalEm, Colors.Normal) + '\n')
472 471 out_list.extend(self._format_list(elist))
473 472 # The exception info should be a single entry in the list.
474 473 lines = ''.join(self._format_exception_only(etype, value))
475 474 out_list.append(lines)
476 475
477 476 # Note: this code originally read:
478 477
479 478 ## for line in lines[:-1]:
480 479 ## out_list.append(" "+line)
481 480 ## out_list.append(lines[-1])
482 481
483 482 # This means it was indenting everything but the last line by a little
484 483 # bit. I've disabled this for now, but if we see ugliness somewhre we
485 484 # can restore it.
486 485
487 486 return out_list
488 487
489 488 def _format_list(self, extracted_list):
490 489 """Format a list of traceback entry tuples for printing.
491 490
492 491 Given a list of tuples as returned by extract_tb() or
493 492 extract_stack(), return a list of strings ready for printing.
494 493 Each string in the resulting list corresponds to the item with the
495 494 same index in the argument list. Each string ends in a newline;
496 495 the strings may contain internal newlines as well, for those items
497 496 whose source text line is not None.
498 497
499 498 Lifted almost verbatim from traceback.py
500 499 """
501 500
502 501 Colors = self.Colors
503 502 list = []
504 503 for filename, lineno, name, line in extracted_list[:-1]:
505 504 item = ' File %s"%s"%s, line %s%d%s, in %s%s%s\n' % \
506 505 (Colors.filename, filename, Colors.Normal,
507 506 Colors.lineno, lineno, Colors.Normal,
508 507 Colors.name, name, Colors.Normal)
509 508 if line:
510 509 item = item + ' %s\n' % line.strip()
511 510 list.append(item)
512 511 # Emphasize the last entry
513 512 filename, lineno, name, line = extracted_list[-1]
514 513 item = '%s File %s"%s"%s, line %s%d%s, in %s%s%s%s\n' % \
515 514 (Colors.normalEm,
516 515 Colors.filenameEm, filename, Colors.normalEm,
517 516 Colors.linenoEm, lineno, Colors.normalEm,
518 517 Colors.nameEm, name, Colors.normalEm,
519 518 Colors.Normal)
520 519 if line:
521 520 item = item + '%s %s%s\n' % (Colors.line, line.strip(),
522 521 Colors.Normal)
523 522 list.append(item)
524 523 #from pprint import pformat; print 'LISTTB', pformat(list) # dbg
525 524 return list
526 525
527 526 def _format_exception_only(self, etype, value):
528 527 """Format the exception part of a traceback.
529 528
530 529 The arguments are the exception type and value such as given by
531 530 sys.exc_info()[:2]. The return value is a list of strings, each ending
532 531 in a newline. Normally, the list contains a single string; however,
533 532 for SyntaxError exceptions, it contains several lines that (when
534 533 printed) display detailed information about where the syntax error
535 534 occurred. The message indicating which exception occurred is the
536 535 always last string in the list.
537 536
538 537 Also lifted nearly verbatim from traceback.py
539 538 """
540 539
541 540 have_filedata = False
542 541 Colors = self.Colors
543 542 list = []
544 543 try:
545 544 stype = Colors.excName + etype.__name__ + Colors.Normal
546 545 except AttributeError:
547 546 stype = etype # String exceptions don't get special coloring
548 547 if value is None:
549 548 list.append( str(stype) + '\n')
550 549 else:
551 550 if etype is SyntaxError:
552 551 try:
553 552 msg, (filename, lineno, offset, line) = value
554 553 except:
555 554 have_filedata = False
556 555 else:
557 556 have_filedata = True
558 557 #print 'filename is',filename # dbg
559 558 if not filename: filename = "<string>"
560 559 list.append('%s File %s"%s"%s, line %s%d%s\n' % \
561 560 (Colors.normalEm,
562 561 Colors.filenameEm, filename, Colors.normalEm,
563 562 Colors.linenoEm, lineno, Colors.Normal ))
564 563 if line is not None:
565 564 i = 0
566 565 while i < len(line) and line[i].isspace():
567 566 i = i+1
568 567 list.append('%s %s%s\n' % (Colors.line,
569 568 line.strip(),
570 569 Colors.Normal))
571 570 if offset is not None:
572 571 s = ' '
573 572 for c in line[i:offset-1]:
574 573 if c.isspace():
575 574 s = s + c
576 575 else:
577 576 s = s + ' '
578 577 list.append('%s%s^%s\n' % (Colors.caret, s,
579 578 Colors.Normal) )
580 579 value = msg
581 580 s = self._some_str(value)
582 581 if s:
583 582 list.append('%s%s:%s %s\n' % (str(stype), Colors.excName,
584 583 Colors.Normal, s))
585 584 else:
586 585 list.append('%s\n' % str(stype))
587 586
588 587 # sync with user hooks
589 588 if have_filedata:
590 589 ipinst = ipapi.get()
591 590 if ipinst is not None:
592 591 ipinst.hooks.synchronize_with_editor(filename, lineno, 0)
593 592
594 593 return list
595 594
596 595 def get_exception_only(self, etype, value):
597 596 """Only print the exception type and message, without a traceback.
598 597
599 598 Parameters
600 599 ----------
601 600 etype : exception type
602 601 value : exception value
603 602 """
604 603 return ListTB.structured_traceback(self, etype, value, [])
605 604
606 605
607 606 def show_exception_only(self, etype, evalue):
608 607 """Only print the exception type and message, without a traceback.
609 608
610 609 Parameters
611 610 ----------
612 611 etype : exception type
613 612 value : exception value
614 613 """
615 614 # This method needs to use __call__ from *this* class, not the one from
616 615 # a subclass whose signature or behavior may be different
617 616 ostream = self.ostream
618 617 ostream.flush()
619 618 ostream.write('\n'.join(self.get_exception_only(etype, evalue)))
620 619 ostream.flush()
621 620
622 621 def _some_str(self, value):
623 622 # Lifted from traceback.py
624 623 try:
625 624 return str(value)
626 625 except:
627 626 return '<unprintable %s object>' % type(value).__name__
628 627
629 628 #----------------------------------------------------------------------------
630 629 class VerboseTB(TBTools):
631 630 """A port of Ka-Ping Yee's cgitb.py module that outputs color text instead
632 631 of HTML. Requires inspect and pydoc. Crazy, man.
633 632
634 633 Modified version which optionally strips the topmost entries from the
635 634 traceback, to be used with alternate interpreters (because their own code
636 635 would appear in the traceback)."""
637 636
638 637 def __init__(self,color_scheme = 'Linux', call_pdb=False, ostream=None,
639 638 tb_offset=0, long_header=False, include_vars=True):
640 639 """Specify traceback offset, headers and color scheme.
641 640
642 641 Define how many frames to drop from the tracebacks. Calling it with
643 642 tb_offset=1 allows use of this handler in interpreters which will have
644 643 their own code at the top of the traceback (VerboseTB will first
645 644 remove that frame before printing the traceback info)."""
646 645 TBTools.__init__(self, color_scheme=color_scheme, call_pdb=call_pdb,
647 646 ostream=ostream)
648 647 self.tb_offset = tb_offset
649 648 self.long_header = long_header
650 649 self.include_vars = include_vars
651 650
652 651 def structured_traceback(self, etype, evalue, etb, tb_offset=None,
653 652 context=5):
654 653 """Return a nice text document describing the traceback."""
655 654
656 655 tb_offset = self.tb_offset if tb_offset is None else tb_offset
657 656
658 657 # some locals
659 658 try:
660 659 etype = etype.__name__
661 660 except AttributeError:
662 661 pass
663 662 Colors = self.Colors # just a shorthand + quicker name lookup
664 663 ColorsNormal = Colors.Normal # used a lot
665 664 col_scheme = self.color_scheme_table.active_scheme_name
666 665 indent = ' '*INDENT_SIZE
667 666 em_normal = '%s\n%s%s' % (Colors.valEm, indent,ColorsNormal)
668 667 undefined = '%sundefined%s' % (Colors.em, ColorsNormal)
669 668 exc = '%s%s%s' % (Colors.excName,etype,ColorsNormal)
670 669
671 670 # some internal-use functions
672 671 def text_repr(value):
673 672 """Hopefully pretty robust repr equivalent."""
674 673 # this is pretty horrible but should always return *something*
675 674 try:
676 675 return pydoc.text.repr(value)
677 676 except KeyboardInterrupt:
678 677 raise
679 678 except:
680 679 try:
681 680 return repr(value)
682 681 except KeyboardInterrupt:
683 682 raise
684 683 except:
685 684 try:
686 685 # all still in an except block so we catch
687 686 # getattr raising
688 687 name = getattr(value, '__name__', None)
689 688 if name:
690 689 # ick, recursion
691 690 return text_repr(name)
692 691 klass = getattr(value, '__class__', None)
693 692 if klass:
694 693 return '%s instance' % text_repr(klass)
695 694 except KeyboardInterrupt:
696 695 raise
697 696 except:
698 697 return 'UNRECOVERABLE REPR FAILURE'
699 698 def eqrepr(value, repr=text_repr): return '=%s' % repr(value)
700 699 def nullrepr(value, repr=text_repr): return ''
701 700
702 701 # meat of the code begins
703 702 try:
704 703 etype = etype.__name__
705 704 except AttributeError:
706 705 pass
707 706
708 707 if self.long_header:
709 708 # Header with the exception type, python version, and date
710 pyver = 'Python ' + string.split(sys.version)[0] + ': ' + sys.executable
709 pyver = 'Python ' + sys.version.split()[0] + ': ' + sys.executable
711 710 date = time.ctime(time.time())
712 711
713 712 head = '%s%s%s\n%s%s%s\n%s' % (Colors.topline, '-'*75, ColorsNormal,
714 713 exc, ' '*(75-len(str(etype))-len(pyver)),
715 714 pyver, date.rjust(75) )
716 715 head += "\nA problem occured executing Python code. Here is the sequence of function"\
717 716 "\ncalls leading up to the error, with the most recent (innermost) call last."
718 717 else:
719 718 # Simplified header
720 719 head = '%s%s%s\n%s%s' % (Colors.topline, '-'*75, ColorsNormal,exc,
721 720 'Traceback (most recent call last)'.\
722 721 rjust(75 - len(str(etype)) ) )
723 722 frames = []
724 723 # Flush cache before calling inspect. This helps alleviate some of the
725 724 # problems with python 2.3's inspect.py.
726 725 linecache.checkcache()
727 726 # Drop topmost frames if requested
728 727 try:
729 728 # Try the default getinnerframes and Alex's: Alex's fixes some
730 729 # problems, but it generates empty tracebacks for console errors
731 730 # (5 blanks lines) where none should be returned.
732 731 #records = inspect.getinnerframes(etb, context)[tb_offset:]
733 732 #print 'python records:', records # dbg
734 733 records = _fixed_getinnerframes(etb, context, tb_offset)
735 734 #print 'alex records:', records # dbg
736 735 except:
737 736
738 737 # FIXME: I've been getting many crash reports from python 2.3
739 738 # users, traceable to inspect.py. If I can find a small test-case
740 739 # to reproduce this, I should either write a better workaround or
741 740 # file a bug report against inspect (if that's the real problem).
742 741 # So far, I haven't been able to find an isolated example to
743 742 # reproduce the problem.
744 743 inspect_error()
745 744 traceback.print_exc(file=self.ostream)
746 745 info('\nUnfortunately, your original traceback can not be constructed.\n')
747 746 return ''
748 747
749 748 # build some color string templates outside these nested loops
750 749 tpl_link = '%s%%s%s' % (Colors.filenameEm,ColorsNormal)
751 750 tpl_call = 'in %s%%s%s%%s%s' % (Colors.vName, Colors.valEm,
752 751 ColorsNormal)
753 752 tpl_call_fail = 'in %s%%s%s(***failed resolving arguments***)%s' % \
754 753 (Colors.vName, Colors.valEm, ColorsNormal)
755 754 tpl_local_var = '%s%%s%s' % (Colors.vName, ColorsNormal)
756 755 tpl_global_var = '%sglobal%s %s%%s%s' % (Colors.em, ColorsNormal,
757 756 Colors.vName, ColorsNormal)
758 757 tpl_name_val = '%%s %s= %%s%s' % (Colors.valEm, ColorsNormal)
759 758 tpl_line = '%s%%s%s %%s' % (Colors.lineno, ColorsNormal)
760 759 tpl_line_em = '%s%%s%s %%s%s' % (Colors.linenoEm,Colors.line,
761 760 ColorsNormal)
762 761
763 762 # now, loop over all records printing context and info
764 763 abspath = os.path.abspath
765 764 for frame, file, lnum, func, lines, index in records:
766 765 #print '*** record:',file,lnum,func,lines,index # dbg
767 766 try:
768 767 file = file and abspath(file) or '?'
769 768 except OSError:
770 769 # if file is '<console>' or something not in the filesystem,
771 770 # the abspath call will throw an OSError. Just ignore it and
772 771 # keep the original file string.
773 772 pass
774 773 link = tpl_link % file
775 774 try:
776 775 args, varargs, varkw, locals = inspect.getargvalues(frame)
777 776 except:
778 777 # This can happen due to a bug in python2.3. We should be
779 778 # able to remove this try/except when 2.4 becomes a
780 779 # requirement. Bug details at http://python.org/sf/1005466
781 780 inspect_error()
782 781 traceback.print_exc(file=self.ostream)
783 782 info("\nIPython's exception reporting continues...\n")
784 783
785 784 if func == '?':
786 785 call = ''
787 786 else:
788 787 # Decide whether to include variable details or not
789 788 var_repr = self.include_vars and eqrepr or nullrepr
790 789 try:
791 790 call = tpl_call % (func,inspect.formatargvalues(args,
792 791 varargs, varkw,
793 792 locals,formatvalue=var_repr))
794 793 except KeyError:
795 794 # This happens in situations like errors inside generator
796 795 # expressions, where local variables are listed in the
797 796 # line, but can't be extracted from the frame. I'm not
798 797 # 100% sure this isn't actually a bug in inspect itself,
799 798 # but since there's no info for us to compute with, the
800 799 # best we can do is report the failure and move on. Here
801 800 # we must *not* call any traceback construction again,
802 801 # because that would mess up use of %debug later on. So we
803 802 # simply report the failure and move on. The only
804 803 # limitation will be that this frame won't have locals
805 804 # listed in the call signature. Quite subtle problem...
806 805 # I can't think of a good way to validate this in a unit
807 806 # test, but running a script consisting of:
808 807 # dict( (k,v.strip()) for (k,v) in range(10) )
809 808 # will illustrate the error, if this exception catch is
810 809 # disabled.
811 810 call = tpl_call_fail % func
812 811
813 812 # Initialize a list of names on the current line, which the
814 813 # tokenizer below will populate.
815 814 names = []
816 815
817 816 def tokeneater(token_type, token, start, end, line):
818 817 """Stateful tokeneater which builds dotted names.
819 818
820 819 The list of names it appends to (from the enclosing scope) can
821 820 contain repeated composite names. This is unavoidable, since
822 821 there is no way to disambguate partial dotted structures until
823 822 the full list is known. The caller is responsible for pruning
824 823 the final list of duplicates before using it."""
825 824
826 825 # build composite names
827 826 if token == '.':
828 827 try:
829 828 names[-1] += '.'
830 829 # store state so the next token is added for x.y.z names
831 830 tokeneater.name_cont = True
832 831 return
833 832 except IndexError:
834 833 pass
835 834 if token_type == tokenize.NAME and token not in keyword.kwlist:
836 835 if tokeneater.name_cont:
837 836 # Dotted names
838 837 names[-1] += token
839 838 tokeneater.name_cont = False
840 839 else:
841 840 # Regular new names. We append everything, the caller
842 841 # will be responsible for pruning the list later. It's
843 842 # very tricky to try to prune as we go, b/c composite
844 843 # names can fool us. The pruning at the end is easy
845 844 # to do (or the caller can print a list with repeated
846 845 # names if so desired.
847 846 names.append(token)
848 847 elif token_type == tokenize.NEWLINE:
849 848 raise IndexError
850 849 # we need to store a bit of state in the tokenizer to build
851 850 # dotted names
852 851 tokeneater.name_cont = False
853 852
854 853 def linereader(file=file, lnum=[lnum], getline=linecache.getline):
855 854 line = getline(file, lnum[0])
856 855 lnum[0] += 1
857 856 return line
858 857
859 858 # Build the list of names on this line of code where the exception
860 859 # occurred.
861 860 try:
862 861 # This builds the names list in-place by capturing it from the
863 862 # enclosing scope.
864 863 tokenize.tokenize(linereader, tokeneater)
865 864 except IndexError:
866 865 # signals exit of tokenizer
867 866 pass
868 867 except tokenize.TokenError,msg:
869 868 _m = ("An unexpected error occurred while tokenizing input\n"
870 869 "The following traceback may be corrupted or invalid\n"
871 870 "The error message is: %s\n" % msg)
872 871 error(_m)
873 872
874 873 # prune names list of duplicates, but keep the right order
875 874 unique_names = uniq_stable(names)
876 875
877 876 # Start loop over vars
878 877 lvals = []
879 878 if self.include_vars:
880 879 for name_full in unique_names:
881 880 name_base = name_full.split('.',1)[0]
882 881 if name_base in frame.f_code.co_varnames:
883 882 if locals.has_key(name_base):
884 883 try:
885 884 value = repr(eval(name_full,locals))
886 885 except:
887 886 value = undefined
888 887 else:
889 888 value = undefined
890 889 name = tpl_local_var % name_full
891 890 else:
892 891 if frame.f_globals.has_key(name_base):
893 892 try:
894 893 value = repr(eval(name_full,frame.f_globals))
895 894 except:
896 895 value = undefined
897 896 else:
898 897 value = undefined
899 898 name = tpl_global_var % name_full
900 899 lvals.append(tpl_name_val % (name,value))
901 900 if lvals:
902 901 lvals = '%s%s' % (indent,em_normal.join(lvals))
903 902 else:
904 903 lvals = ''
905 904
906 905 level = '%s %s\n' % (link,call)
907 906
908 907 if index is None:
909 908 frames.append(level)
910 909 else:
911 910 frames.append('%s%s' % (level,''.join(
912 911 _format_traceback_lines(lnum,index,lines,Colors,lvals,
913 912 col_scheme))))
914 913
915 914 # Get (safely) a string form of the exception info
916 915 try:
917 916 etype_str,evalue_str = map(str,(etype,evalue))
918 917 except:
919 918 # User exception is improperly defined.
920 919 etype,evalue = str,sys.exc_info()[:2]
921 920 etype_str,evalue_str = map(str,(etype,evalue))
922 921 # ... and format it
923 922 exception = ['%s%s%s: %s' % (Colors.excName, etype_str,
924 923 ColorsNormal, evalue_str)]
925 924 if type(evalue) is types.InstanceType:
926 925 try:
927 926 names = [w for w in dir(evalue) if isinstance(w, basestring)]
928 927 except:
929 928 # Every now and then, an object with funny inernals blows up
930 929 # when dir() is called on it. We do the best we can to report
931 930 # the problem and continue
932 931 _m = '%sException reporting error (object with broken dir())%s:'
933 932 exception.append(_m % (Colors.excName,ColorsNormal))
934 933 etype_str,evalue_str = map(str,sys.exc_info()[:2])
935 934 exception.append('%s%s%s: %s' % (Colors.excName,etype_str,
936 935 ColorsNormal, evalue_str))
937 936 names = []
938 937 for name in names:
939 938 value = text_repr(getattr(evalue, name))
940 939 exception.append('\n%s%s = %s' % (indent, name, value))
941 940
942 941 # vds: >>
943 942 if records:
944 943 filepath, lnum = records[-1][1:3]
945 944 #print "file:", str(file), "linenb", str(lnum) # dbg
946 945 filepath = os.path.abspath(filepath)
947 946 ipinst = ipapi.get()
948 947 if ipinst is not None:
949 948 ipinst.hooks.synchronize_with_editor(filepath, lnum, 0)
950 949 # vds: <<
951 950
952 951 # return all our info assembled as a single string
953 952 # return '%s\n\n%s\n%s' % (head,'\n'.join(frames),''.join(exception[0]) )
954 953 return [head] + frames + [''.join(exception[0])]
955 954
956 955 def debugger(self,force=False):
957 956 """Call up the pdb debugger if desired, always clean up the tb
958 957 reference.
959 958
960 959 Keywords:
961 960
962 961 - force(False): by default, this routine checks the instance call_pdb
963 962 flag and does not actually invoke the debugger if the flag is false.
964 963 The 'force' option forces the debugger to activate even if the flag
965 964 is false.
966 965
967 966 If the call_pdb flag is set, the pdb interactive debugger is
968 967 invoked. In all cases, the self.tb reference to the current traceback
969 968 is deleted to prevent lingering references which hamper memory
970 969 management.
971 970
972 971 Note that each call to pdb() does an 'import readline', so if your app
973 972 requires a special setup for the readline completers, you'll have to
974 973 fix that by hand after invoking the exception handler."""
975 974
976 975 if force or self.call_pdb:
977 976 if self.pdb is None:
978 977 self.pdb = debugger.Pdb(
979 978 self.color_scheme_table.active_scheme_name)
980 979 # the system displayhook may have changed, restore the original
981 980 # for pdb
982 981 display_trap = DisplayTrap(hook=sys.__displayhook__)
983 982 with display_trap:
984 983 self.pdb.reset()
985 984 # Find the right frame so we don't pop up inside ipython itself
986 985 if hasattr(self,'tb') and self.tb is not None:
987 986 etb = self.tb
988 987 else:
989 988 etb = self.tb = sys.last_traceback
990 989 while self.tb is not None and self.tb.tb_next is not None:
991 990 self.tb = self.tb.tb_next
992 991 if etb and etb.tb_next:
993 992 etb = etb.tb_next
994 993 self.pdb.botframe = etb.tb_frame
995 994 self.pdb.interaction(self.tb.tb_frame, self.tb)
996 995
997 996 if hasattr(self,'tb'):
998 997 del self.tb
999 998
1000 999 def handler(self, info=None):
1001 1000 (etype, evalue, etb) = info or sys.exc_info()
1002 1001 self.tb = etb
1003 1002 ostream = self.ostream
1004 1003 ostream.flush()
1005 1004 ostream.write(self.text(etype, evalue, etb))
1006 1005 ostream.write('\n')
1007 1006 ostream.flush()
1008 1007
1009 1008 # Changed so an instance can just be called as VerboseTB_inst() and print
1010 1009 # out the right info on its own.
1011 1010 def __call__(self, etype=None, evalue=None, etb=None):
1012 1011 """This hook can replace sys.excepthook (for Python 2.1 or higher)."""
1013 1012 if etb is None:
1014 1013 self.handler()
1015 1014 else:
1016 1015 self.handler((etype, evalue, etb))
1017 1016 try:
1018 1017 self.debugger()
1019 1018 except KeyboardInterrupt:
1020 1019 print "\nKeyboardInterrupt"
1021 1020
1022 1021 #----------------------------------------------------------------------------
1023 1022 class FormattedTB(VerboseTB, ListTB):
1024 1023 """Subclass ListTB but allow calling with a traceback.
1025 1024
1026 1025 It can thus be used as a sys.excepthook for Python > 2.1.
1027 1026
1028 1027 Also adds 'Context' and 'Verbose' modes, not available in ListTB.
1029 1028
1030 1029 Allows a tb_offset to be specified. This is useful for situations where
1031 1030 one needs to remove a number of topmost frames from the traceback (such as
1032 1031 occurs with python programs that themselves execute other python code,
1033 1032 like Python shells). """
1034 1033
1035 1034 def __init__(self, mode='Plain', color_scheme='Linux', call_pdb=False,
1036 1035 ostream=None,
1037 1036 tb_offset=0, long_header=False, include_vars=False):
1038 1037
1039 1038 # NEVER change the order of this list. Put new modes at the end:
1040 1039 self.valid_modes = ['Plain','Context','Verbose']
1041 1040 self.verbose_modes = self.valid_modes[1:3]
1042 1041
1043 1042 VerboseTB.__init__(self, color_scheme=color_scheme, call_pdb=call_pdb,
1044 1043 ostream=ostream, tb_offset=tb_offset,
1045 1044 long_header=long_header, include_vars=include_vars)
1046 1045
1047 1046 # Different types of tracebacks are joined with different separators to
1048 1047 # form a single string. They are taken from this dict
1049 1048 self._join_chars = dict(Plain='', Context='\n', Verbose='\n')
1050 1049 # set_mode also sets the tb_join_char attribute
1051 1050 self.set_mode(mode)
1052 1051
1053 1052 def _extract_tb(self,tb):
1054 1053 if tb:
1055 1054 return traceback.extract_tb(tb)
1056 1055 else:
1057 1056 return None
1058 1057
1059 1058 def structured_traceback(self, etype, value, tb, tb_offset=None, context=5):
1060 1059 tb_offset = self.tb_offset if tb_offset is None else tb_offset
1061 1060 mode = self.mode
1062 1061 if mode in self.verbose_modes:
1063 1062 # Verbose modes need a full traceback
1064 1063 return VerboseTB.structured_traceback(
1065 1064 self, etype, value, tb, tb_offset, context
1066 1065 )
1067 1066 else:
1068 1067 # We must check the source cache because otherwise we can print
1069 1068 # out-of-date source code.
1070 1069 linecache.checkcache()
1071 1070 # Now we can extract and format the exception
1072 1071 elist = self._extract_tb(tb)
1073 1072 return ListTB.structured_traceback(
1074 1073 self, etype, value, elist, tb_offset, context
1075 1074 )
1076 1075
1077 1076 def stb2text(self, stb):
1078 1077 """Convert a structured traceback (a list) to a string."""
1079 1078 return self.tb_join_char.join(stb)
1080 1079
1081 1080
1082 1081 def set_mode(self,mode=None):
1083 1082 """Switch to the desired mode.
1084 1083
1085 1084 If mode is not specified, cycles through the available modes."""
1086 1085
1087 1086 if not mode:
1088 1087 new_idx = ( self.valid_modes.index(self.mode) + 1 ) % \
1089 1088 len(self.valid_modes)
1090 1089 self.mode = self.valid_modes[new_idx]
1091 1090 elif mode not in self.valid_modes:
1092 1091 raise ValueError, 'Unrecognized mode in FormattedTB: <'+mode+'>\n'\
1093 1092 'Valid modes: '+str(self.valid_modes)
1094 1093 else:
1095 1094 self.mode = mode
1096 1095 # include variable details only in 'Verbose' mode
1097 1096 self.include_vars = (self.mode == self.valid_modes[2])
1098 1097 # Set the join character for generating text tracebacks
1099 1098 self.tb_join_char = self._join_chars[self.mode]
1100 1099
1101 1100 # some convenient shorcuts
1102 1101 def plain(self):
1103 1102 self.set_mode(self.valid_modes[0])
1104 1103
1105 1104 def context(self):
1106 1105 self.set_mode(self.valid_modes[1])
1107 1106
1108 1107 def verbose(self):
1109 1108 self.set_mode(self.valid_modes[2])
1110 1109
1111 1110 #----------------------------------------------------------------------------
1112 1111 class AutoFormattedTB(FormattedTB):
1113 1112 """A traceback printer which can be called on the fly.
1114 1113
1115 1114 It will find out about exceptions by itself.
1116 1115
1117 1116 A brief example:
1118 1117
1119 1118 AutoTB = AutoFormattedTB(mode = 'Verbose',color_scheme='Linux')
1120 1119 try:
1121 1120 ...
1122 1121 except:
1123 1122 AutoTB() # or AutoTB(out=logfile) where logfile is an open file object
1124 1123 """
1125 1124
1126 1125 def __call__(self,etype=None,evalue=None,etb=None,
1127 1126 out=None,tb_offset=None):
1128 1127 """Print out a formatted exception traceback.
1129 1128
1130 1129 Optional arguments:
1131 1130 - out: an open file-like object to direct output to.
1132 1131
1133 1132 - tb_offset: the number of frames to skip over in the stack, on a
1134 1133 per-call basis (this overrides temporarily the instance's tb_offset
1135 1134 given at initialization time. """
1136 1135
1137 1136
1138 1137 if out is None:
1139 1138 out = self.ostream
1140 1139 out.flush()
1141 1140 out.write(self.text(etype, evalue, etb, tb_offset))
1142 1141 out.write('\n')
1143 1142 out.flush()
1144 1143 # FIXME: we should remove the auto pdb behavior from here and leave
1145 1144 # that to the clients.
1146 1145 try:
1147 1146 self.debugger()
1148 1147 except KeyboardInterrupt:
1149 1148 print "\nKeyboardInterrupt"
1150 1149
1151 1150 def structured_traceback(self, etype=None, value=None, tb=None,
1152 1151 tb_offset=None, context=5):
1153 1152 if etype is None:
1154 1153 etype,value,tb = sys.exc_info()
1155 1154 self.tb = tb
1156 1155 return FormattedTB.structured_traceback(
1157 1156 self, etype, value, tb, tb_offset, context)
1158 1157
1159 1158 #---------------------------------------------------------------------------
1160 1159
1161 1160 # A simple class to preserve Nathan's original functionality.
1162 1161 class ColorTB(FormattedTB):
1163 1162 """Shorthand to initialize a FormattedTB in Linux colors mode."""
1164 1163 def __init__(self,color_scheme='Linux',call_pdb=0):
1165 1164 FormattedTB.__init__(self,color_scheme=color_scheme,
1166 1165 call_pdb=call_pdb)
1167 1166
1168 1167
1169 1168 class SyntaxTB(ListTB):
1170 1169 """Extension which holds some state: the last exception value"""
1171 1170
1172 1171 def __init__(self,color_scheme = 'NoColor'):
1173 1172 ListTB.__init__(self,color_scheme)
1174 1173 self.last_syntax_error = None
1175 1174
1176 1175 def __call__(self, etype, value, elist):
1177 1176 self.last_syntax_error = value
1178 1177 ListTB.__call__(self,etype,value,elist)
1179 1178
1180 1179 def clear_err_state(self):
1181 1180 """Return the current error state and clear it"""
1182 1181 e = self.last_syntax_error
1183 1182 self.last_syntax_error = None
1184 1183 return e
1185 1184
1186 1185 def stb2text(self, stb):
1187 1186 """Convert a structured traceback (a list) to a string."""
1188 1187 return ''.join(stb)
1189 1188
1190 1189
1191 1190 #----------------------------------------------------------------------------
1192 1191 # module testing (minimal)
1193 1192 if __name__ == "__main__":
1194 1193 def spam(c, (d, e)):
1195 1194 x = c + d
1196 1195 y = c * d
1197 1196 foo(x, y)
1198 1197
1199 1198 def foo(a, b, bar=1):
1200 1199 eggs(a, b + bar)
1201 1200
1202 1201 def eggs(f, g, z=globals()):
1203 1202 h = f + g
1204 1203 i = f - g
1205 1204 return h / i
1206 1205
1207 1206 print ''
1208 1207 print '*** Before ***'
1209 1208 try:
1210 1209 print spam(1, (2, 3))
1211 1210 except:
1212 1211 traceback.print_exc()
1213 1212 print ''
1214 1213
1215 1214 handler = ColorTB()
1216 1215 print '*** ColorTB ***'
1217 1216 try:
1218 1217 print spam(1, (2, 3))
1219 1218 except:
1220 1219 apply(handler, sys.exc_info() )
1221 1220 print ''
1222 1221
1223 1222 handler = VerboseTB()
1224 1223 print '*** VerboseTB ***'
1225 1224 try:
1226 1225 print spam(1, (2, 3))
1227 1226 except:
1228 1227 apply(handler, sys.exc_info() )
1229 1228 print ''
1230 1229
General Comments 0
You need to be logged in to leave comments. Login now