tb.py 4.02 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 8
from stat import *
import string
Guido van Rossum's avatar
Guido van Rossum committed
9
import linecache
Guido van Rossum's avatar
Guido van Rossum committed
10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39

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:
Guido van Rossum's avatar
Guido van Rossum committed
40
			if cmd == 'quit':
Guido van Rossum's avatar
Guido van Rossum committed
41
				break
Guido van Rossum's avatar
Guido van Rossum committed
42
			elif cmd == 'list':
Guido van Rossum's avatar
Guido van Rossum committed
43
				browserlist(tb)
Guido van Rossum's avatar
Guido van Rossum committed
44
			elif cmd == 'up':
Guido van Rossum's avatar
Guido van Rossum committed
45 46
				if ptr-1 >= 0: ptr = ptr-1
				else: print 'Bottom of stack.'
Guido van Rossum's avatar
Guido van Rossum committed
47
			elif cmd == 'down':
Guido van Rossum's avatar
Guido van Rossum committed
48 49
				if ptr+1 < len(tblist): ptr = ptr+1
				else: print 'Top of stack.'
Guido van Rossum's avatar
Guido van Rossum committed
50
			elif cmd == 'locals':
Guido van Rossum's avatar
Guido van Rossum committed
51
				printsymbols(tb.tb_frame.f_locals)
Guido van Rossum's avatar
Guido van Rossum committed
52
			elif cmd == 'globals':
Guido van Rossum's avatar
Guido van Rossum committed
53 54 55 56 57 58 59 60 61 62 63 64
				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):
Guido van Rossum's avatar
Guido van Rossum committed
65
		if i == lineno: prefix = '***' + string.rjust(`i`, 4) + ':'
Guido van Rossum's avatar
Guido van Rossum committed
66
		else: prefix = string.rjust(`i`, 7) + ':'
Guido van Rossum's avatar
Guido van Rossum committed
67
		line = linecache.getline(filename, i)
Guido van Rossum's avatar
Guido van Rossum committed
68
		if line[-1:] == '\n': line = line[:-1]
Guido van Rossum's avatar
Guido van Rossum committed
69 70 71 72 73 74
		print prefix + line

def browserexec(tb, cmd):
	locals = tb.tb_frame.f_locals
	globals = tb.tb_frame.f_globals
	try:
75
		exec cmd+'\n' in globals, locals
Guido van Rossum's avatar
Guido van Rossum committed
76
	except:
77
		t, v = sys.exc_info()[:2]
Guido van Rossum's avatar
Guido van Rossum committed
78
		print '*** Exception:',
79 80
		if type(t) == type(''):
			print t,
81
		else:
82 83 84
			print t.__name__,
		if v <> None:
			print ':', v,
Guido van Rossum's avatar
Guido van Rossum committed
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 115
		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
116
	line = linecache.getline(filename, lineno)
Guido van Rossum's avatar
Guido van Rossum committed
117 118 119 120 121 122 123 124 125 126 127 128 129
	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):
Guido van Rossum's avatar
Guido van Rossum committed
130
	if v == None:
Guido van Rossum's avatar
Guido van Rossum committed
131 132 133
		print 'None',
	elif type(v) in (type(0), type(0.0)):
		print v,
Guido van Rossum's avatar
Guido van Rossum committed
134
	elif type(v) == type(''):
Guido van Rossum's avatar
Guido van Rossum committed
135 136 137 138
		if len(v) > 20:
			print `v[:17] + '...'`,
		else:
			print `v`,
Guido van Rossum's avatar
Guido van Rossum committed
139
	elif type(v) == type(()):
Guido van Rossum's avatar
Guido van Rossum committed
140 141 142
		print '(',
		printlist(v, maxlevel)
		print ')',
Guido van Rossum's avatar
Guido van Rossum committed
143
	elif type(v) == type([]):
Guido van Rossum's avatar
Guido van Rossum committed
144 145 146
		print '[',
		printlist(v, maxlevel)
		print ']',
Guido van Rossum's avatar
Guido van Rossum committed
147
	elif type(v) == type({}):
Guido van Rossum's avatar
Guido van Rossum committed
148 149 150 151 152 153 154 155
		print '{',
		printdict(v, maxlevel)
		print '}',
	else:
		print v,

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