tb.py 4.9 KB

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