cpython/Lib/tb.py

179 lines
4.0 KiB
Python
Raw Normal View History

1990-12-26 11:40:07 -04:00
# Print tracebacks, with a dump of local variables.
# Also an interactive stack trace browser.
1995-08-10 16:43:04 -03:00
# Note -- this module is obsolete -- use pdb.pm() instead.
1990-12-26 11:40:07 -04:00
import sys
import os
1990-12-26 11:40:07 -04:00
from stat import *
import string
import linecache
1990-12-26 11:40:07 -04:00
def br(): browser(sys.last_traceback)
def tb(): printtb(sys.last_traceback)
def browser(tb):
if not tb:
print 'No traceback.'
return
tblist = []
while tb:
tblist.append(tb)
tb = tb.tb_next
ptr = len(tblist)-1
tb = tblist[ptr]
while 1:
if tb <> tblist[ptr]:
tb = tblist[ptr]
print `ptr` + ':',
printtbheader(tb)
try:
line = raw_input('TB: ')
except KeyboardInterrupt:
print '\n[Interrupted]'
break
except EOFError:
print '\n[EOF]'
break
cmd = string.strip(line)
if cmd:
1992-01-01 15:35:13 -04:00
if cmd == 'quit':
1990-12-26 11:40:07 -04:00
break
1992-01-01 15:35:13 -04:00
elif cmd == 'list':
1990-12-26 11:40:07 -04:00
browserlist(tb)
1992-01-01 15:35:13 -04:00
elif cmd == 'up':
1990-12-26 11:40:07 -04:00
if ptr-1 >= 0: ptr = ptr-1
else: print 'Bottom of stack.'
1992-01-01 15:35:13 -04:00
elif cmd == 'down':
1990-12-26 11:40:07 -04:00
if ptr+1 < len(tblist): ptr = ptr+1
else: print 'Top of stack.'
1992-01-01 15:35:13 -04:00
elif cmd == 'locals':
1990-12-26 11:40:07 -04:00
printsymbols(tb.tb_frame.f_locals)
1992-01-01 15:35:13 -04:00
elif cmd == 'globals':
1990-12-26 11:40:07 -04:00
printsymbols(tb.tb_frame.f_globals)
elif cmd in ('?', 'help'):
browserhelp()
else:
browserexec(tb, cmd)
def browserlist(tb):
filename = tb.tb_frame.f_code.co_filename
lineno = tb.tb_lineno
last = lineno
first = max(1, last-10)
for i in range(first, last+1):
1992-01-01 15:35:13 -04:00
if i == lineno: prefix = '***' + string.rjust(`i`, 4) + ':'
1990-12-26 11:40:07 -04:00
else: prefix = string.rjust(`i`, 7) + ':'
line = linecache.getline(filename, i)
1992-01-01 15:35:13 -04:00
if line[-1:] == '\n': line = line[:-1]
1990-12-26 11:40:07 -04:00
print prefix + line
def browserexec(tb, cmd):
locals = tb.tb_frame.f_locals
globals = tb.tb_frame.f_globals
try:
1995-08-10 16:43:04 -03:00
exec cmd+'\n' in globals, locals
1990-12-26 11:40:07 -04:00
except:
1997-09-29 20:22:12 -03:00
t, v = sys.exc_info()[:2]
1990-12-26 11:40:07 -04:00
print '*** Exception:',
1997-09-29 20:22:12 -03:00
if type(t) == type(''):
print t,
1995-02-27 09:15:45 -04:00
else:
1997-09-29 20:22:12 -03:00
print t.__name__,
if v <> None:
print ':', v,
1990-12-26 11:40:07 -04:00
print
print 'Type help to get help.'
def browserhelp():
print
print ' This is the traceback browser. Commands are:'
print ' up : move one level up in the call stack'
print ' down : move one level down in the call stack'
print ' locals : print all local variables at this level'
print ' globals : print all global variables at this level'
print ' list : list source code around the failure'
print ' help : print help (what you are reading now)'
print ' quit : back to command interpreter'
print ' Typing any other 1-line statement will execute it'
print ' using the current level\'s symbol tables'
print
def printtb(tb):
while tb:
print1tb(tb)
tb = tb.tb_next
def print1tb(tb):
printtbheader(tb)
if tb.tb_frame.f_locals is not tb.tb_frame.f_globals:
printsymbols(tb.tb_frame.f_locals)
def printtbheader(tb):
filename = tb.tb_frame.f_code.co_filename
lineno = tb.tb_lineno
info = '"' + filename + '"(' + `lineno` + ')'
line = linecache.getline(filename, lineno)
1990-12-26 11:40:07 -04:00
if line:
info = info + ': ' + string.strip(line)
print info
def printsymbols(d):
keys = d.keys()
keys.sort()
for name in keys:
print ' ' + string.ljust(name, 12) + ':',
printobject(d[name], 4)
print
def printobject(v, maxlevel):
1992-01-01 15:35:13 -04:00
if v == None:
1990-12-26 11:40:07 -04:00
print 'None',
elif type(v) in (type(0), type(0.0)):
print v,
1992-01-01 15:35:13 -04:00
elif type(v) == type(''):
1990-12-26 11:40:07 -04:00
if len(v) > 20:
print `v[:17] + '...'`,
else:
print `v`,
1992-01-01 15:35:13 -04:00
elif type(v) == type(()):
1990-12-26 11:40:07 -04:00
print '(',
printlist(v, maxlevel)
print ')',
1992-01-01 15:35:13 -04:00
elif type(v) == type([]):
1990-12-26 11:40:07 -04:00
print '[',
printlist(v, maxlevel)
print ']',
1992-01-01 15:35:13 -04:00
elif type(v) == type({}):
1990-12-26 11:40:07 -04:00
print '{',
printdict(v, maxlevel)
print '}',
else:
print v,
def printlist(v, maxlevel):
n = len(v)
1992-01-01 15:35:13 -04:00
if n == 0: return
1990-12-26 11:40:07 -04:00
if maxlevel <= 0:
print '...',
return
for i in range(min(6, n)):
printobject(v[i], maxlevel-1)
if i+1 < n: print ',',
if n > 6: print '...',
def printdict(v, maxlevel):
keys = v.keys()
n = len(keys)
1992-01-01 15:35:13 -04:00
if n == 0: return
1990-12-26 11:40:07 -04:00
if maxlevel <= 0:
print '...',
return
keys.sort()
for i in range(min(6, n)):
key = keys[i]
print `key` + ':',
printobject(v[key], maxlevel-1)
if i+1 < n: print ',',
if n > 6: print '...',