home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / pyth_os2.zip / python-1.0.2 / Lib / tb.py < prev    next >
Text File  |  1993-12-29  |  4KB  |  174 lines

  1. # Print tracebacks, with a dump of local variables.
  2. # Also an interactive stack trace browser.
  3.  
  4. import sys
  5. import os
  6. from stat import *
  7. import string
  8. import linecache
  9.  
  10. def br(): browser(sys.last_traceback)
  11.  
  12. def tb(): printtb(sys.last_traceback)
  13.  
  14. def browser(tb):
  15.     if not tb:
  16.         print 'No traceback.'
  17.         return
  18.     tblist = []
  19.     while tb:
  20.         tblist.append(tb)
  21.         tb = tb.tb_next
  22.     ptr = len(tblist)-1
  23.     tb = tblist[ptr]
  24.     while 1:
  25.         if tb <> tblist[ptr]:
  26.             tb = tblist[ptr]
  27.             print `ptr` + ':',
  28.             printtbheader(tb)
  29.         try:
  30.             line = raw_input('TB: ')
  31.         except KeyboardInterrupt:
  32.             print '\n[Interrupted]'
  33.             break
  34.         except EOFError:
  35.             print '\n[EOF]'
  36.             break
  37.         cmd = string.strip(line)
  38.         if cmd:
  39.             if cmd == 'quit':
  40.                 break
  41.             elif cmd == 'list':
  42.                 browserlist(tb)
  43.             elif cmd == 'up':
  44.                 if ptr-1 >= 0: ptr = ptr-1
  45.                 else: print 'Bottom of stack.'
  46.             elif cmd == 'down':
  47.                 if ptr+1 < len(tblist): ptr = ptr+1
  48.                 else: print 'Top of stack.'
  49.             elif cmd == 'locals':
  50.                 printsymbols(tb.tb_frame.f_locals)
  51.             elif cmd == 'globals':
  52.                 printsymbols(tb.tb_frame.f_globals)
  53.             elif cmd in ('?', 'help'):
  54.                 browserhelp()
  55.             else:
  56.                 browserexec(tb, cmd)
  57.  
  58. def browserlist(tb):
  59.     filename = tb.tb_frame.f_code.co_filename
  60.     lineno = tb.tb_lineno
  61.     last = lineno
  62.     first = max(1, last-10)
  63.     for i in range(first, last+1):
  64.         if i == lineno: prefix = '***' + string.rjust(`i`, 4) + ':'
  65.         else: prefix = string.rjust(`i`, 7) + ':'
  66.         line = linecache.getline(filename, i)
  67.         if line[-1:] == '\n': line = line[:-1]
  68.         print prefix + line
  69.  
  70. def browserexec(tb, cmd):
  71.     locals = tb.tb_frame.f_locals
  72.     globals = tb.tb_frame.f_globals
  73.     try:
  74.         exec(cmd+'\n', globals, locals)
  75.     except:
  76.         print '*** Exception:',
  77.         print sys.exc_type,
  78.         if sys.exc_value <> None:
  79.             print ':', sys.exc_value,
  80.         print
  81.         print 'Type help to get help.'
  82.  
  83. def browserhelp():
  84.     print
  85.     print '    This is the traceback browser.  Commands are:'
  86.     print '        up      : move one level up in the call stack'
  87.     print '        down    : move one level down in the call stack'
  88.     print '        locals  : print all local variables at this level'
  89.     print '        globals : print all global variables at this level'
  90.     print '        list    : list source code around the failure'
  91.     print '        help    : print help (what you are reading now)'
  92.     print '        quit    : back to command interpreter'
  93.     print '    Typing any other 1-line statement will execute it'
  94.     print '    using the current level\'s symbol tables'
  95.     print
  96.  
  97. def printtb(tb):
  98.     while tb:
  99.         print1tb(tb)
  100.         tb = tb.tb_next
  101.  
  102. def print1tb(tb):
  103.     printtbheader(tb)
  104.     if tb.tb_frame.f_locals is not tb.tb_frame.f_globals:
  105.         printsymbols(tb.tb_frame.f_locals)
  106.  
  107. def printtbheader(tb):
  108.     filename = tb.tb_frame.f_code.co_filename
  109.     lineno = tb.tb_lineno
  110.     info = '"' + filename + '"(' + `lineno` + ')'
  111.     line = linecache.getline(filename, lineno)
  112.     if line:
  113.         info = info + ': ' + string.strip(line)
  114.     print info
  115.  
  116. def printsymbols(d):
  117.     keys = d.keys()
  118.     keys.sort()
  119.     for name in keys:
  120.         print '  ' + string.ljust(name, 12) + ':',
  121.         printobject(d[name], 4)
  122.         print
  123.  
  124. def printobject(v, maxlevel):
  125.     if v == None:
  126.         print 'None',
  127.     elif type(v) in (type(0), type(0.0)):
  128.         print v,
  129.     elif type(v) == type(''):
  130.         if len(v) > 20:
  131.             print `v[:17] + '...'`,
  132.         else:
  133.             print `v`,
  134.     elif type(v) == type(()):
  135.         print '(',
  136.         printlist(v, maxlevel)
  137.         print ')',
  138.     elif type(v) == type([]):
  139.         print '[',
  140.         printlist(v, maxlevel)
  141.         print ']',
  142.     elif type(v) == type({}):
  143.         print '{',
  144.         printdict(v, maxlevel)
  145.         print '}',
  146.     else:
  147.         print v,
  148.  
  149. def printlist(v, maxlevel):
  150.     n = len(v)
  151.     if n == 0: return
  152.     if maxlevel <= 0:
  153.         print '...',
  154.         return
  155.     for i in range(min(6, n)):
  156.         printobject(v[i], maxlevel-1)
  157.         if i+1 < n: print ',',
  158.     if n > 6: print '...',
  159.  
  160. def printdict(v, maxlevel):
  161.     keys = v.keys()
  162.     n = len(keys)
  163.     if n == 0: return
  164.     if maxlevel <= 0:
  165.         print '...',
  166.         return
  167.     keys.sort()
  168.     for i in range(min(6, n)):
  169.         key = keys[i]
  170.         print `key` + ':',
  171.         printobject(v[key], maxlevel-1)
  172.         if i+1 < n: print ',',
  173.     if n > 6: print '...',
  174.