tb.py 3.98 KB
Newer Older
Guido van Rossum's avatar
Guido van Rossum committed
1 2
# Print tracebacks, with a dump of local variables.
# Also an interactive stack trace browser.
3
# Note -- this module is obsolete -- use pdb.pm() instead.
Guido van Rossum's avatar
Guido van Rossum committed
4 5

import sys
Guido van Rossum's avatar
Guido van Rossum committed
6
import os
Guido van Rossum's avatar
Guido van Rossum committed
7
from stat import *
Guido van Rossum's avatar
Guido van Rossum committed
8
import linecache
Guido van Rossum's avatar
Guido van Rossum committed
9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24

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:
25
		if tb != tblist[ptr]:
Guido van Rossum's avatar
Guido van Rossum committed
26 27 28 29 30 31 32 33 34 35 36
			tb = tblist[ptr]
			print `ptr` + ':',
			printtbheader(tb)
		try:
			line = raw_input('TB: ')
		except KeyboardInterrupt:
			print '\n[Interrupted]'
			break
		except EOFError:
			print '\n[EOF]'
			break
37
		cmd = line.strip()
Guido van Rossum's avatar
Guido van Rossum committed
38
		if cmd:
Guido van Rossum's avatar
Guido van Rossum committed
39
			if cmd == 'quit':
Guido van Rossum's avatar
Guido van Rossum committed
40
				break
Guido van Rossum's avatar
Guido van Rossum committed
41
			elif cmd == 'list':
Guido van Rossum's avatar
Guido van Rossum committed
42
				browserlist(tb)
Guido van Rossum's avatar
Guido van Rossum committed
43
			elif cmd == 'up':
Guido van Rossum's avatar
Guido van Rossum committed
44 45
				if ptr-1 >= 0: ptr = ptr-1
				else: print 'Bottom of stack.'
Guido van Rossum's avatar
Guido van Rossum committed
46
			elif cmd == 'down':
Guido van Rossum's avatar
Guido van Rossum committed
47 48
				if ptr+1 < len(tblist): ptr = ptr+1
				else: print 'Top of stack.'
Guido van Rossum's avatar
Guido van Rossum committed
49
			elif cmd == 'locals':
Guido van Rossum's avatar
Guido van Rossum committed
50
				printsymbols(tb.tb_frame.f_locals)
Guido van Rossum's avatar
Guido van Rossum committed
51
			elif cmd == 'globals':
Guido van Rossum's avatar
Guido van Rossum committed
52 53 54 55 56 57 58 59 60 61 62 63
				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):
64 65
		if i == lineno: prefix = '***' + `i`.rjust(4) + ':'
		else: prefix = `i`.rjust(7) + ':'
Guido van Rossum's avatar
Guido van Rossum committed
66
		line = linecache.getline(filename, i)
Guido van Rossum's avatar
Guido van Rossum committed
67
		if line[-1:] == '\n': line = line[:-1]
Guido van Rossum's avatar
Guido van Rossum committed
68 69 70 71 72 73
		print prefix + line

def browserexec(tb, cmd):
	locals = tb.tb_frame.f_locals
	globals = tb.tb_frame.f_globals
	try:
74
		exec cmd+'\n' in globals, locals
Guido van Rossum's avatar
Guido van Rossum committed
75
	except:
76
		t, v = sys.exc_info()[:2]
Guido van Rossum's avatar
Guido van Rossum committed
77
		print '*** Exception:',
78
		if type(t) is type(''):
79
			print t,
80
		else:
81
			print t.__name__,
82
		if v is not None:
83
			print ':', v,
Guido van Rossum's avatar
Guido van Rossum committed
84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114
		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` + ')'
Guido van Rossum's avatar
Guido van Rossum committed
115
	line = linecache.getline(filename, lineno)
Guido van Rossum's avatar
Guido van Rossum committed
116
	if line:
117
		info = info + ': ' + line.strip()
Guido van Rossum's avatar
Guido van Rossum committed
118 119 120 121 122 123
	print info

def printsymbols(d):
	keys = d.keys()
	keys.sort()
	for name in keys:
124
		print '  ' + name.ljust(12) + ':',
Guido van Rossum's avatar
Guido van Rossum committed
125 126 127 128
		printobject(d[name], 4)
		print

def printobject(v, maxlevel):
129
	if v is None:
Guido van Rossum's avatar
Guido van Rossum committed
130 131 132
		print 'None',
	elif type(v) in (type(0), type(0.0)):
		print v,
133
	elif type(v) is type(''):
Guido van Rossum's avatar
Guido van Rossum committed
134 135 136 137
		if len(v) > 20:
			print `v[:17] + '...'`,
		else:
			print `v`,
138
	elif type(v) is type(()):
Guido van Rossum's avatar
Guido van Rossum committed
139 140 141
		print '(',
		printlist(v, maxlevel)
		print ')',
142
	elif type(v) is type([]):
Guido van Rossum's avatar
Guido van Rossum committed
143 144 145
		print '[',
		printlist(v, maxlevel)
		print ']',
146
	elif type(v) is type({}):
Guido van Rossum's avatar
Guido van Rossum committed
147 148 149 150 151 152 153 154
		print '{',
		printdict(v, maxlevel)
		print '}',
	else:
		print v,

def printlist(v, maxlevel):
	n = len(v)
Guido van Rossum's avatar
Guido van Rossum committed
155
	if n == 0: return
Guido van Rossum's avatar
Guido van Rossum committed
156 157 158 159 160 161 162 163 164 165 166
	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)
Guido van Rossum's avatar
Guido van Rossum committed
167
	if n == 0: return
Guido van Rossum's avatar
Guido van Rossum committed
168 169 170 171 172 173 174 175 176 177
	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 '...',