| # Print tracebacks, with a dump of local variables. |
| # Also an interactive stack trace browser. |
| |
| import sys |
| import os |
| from statimport* |
| import string |
| import linecache |
| |
| def br(): browser(sys.last_traceback) |
| |
| def tb(): printtb(sys.last_traceback) |
| |
| def browser(tb): |
| ifnot tb: |
| print'No traceback.' |
| return |
| tblist=[] |
| while tb: |
| tblist.append(tb) |
| tb= tb.tb_next |
| ptr= len(tblist)-1 |
| tb= tblist[ptr] |
| while1: |
| if tb<> tblist[ptr]: |
| tb= tblist[ptr] |
| print`ptr`+':', |
| printtbheader(tb) |
| try: |
| line= raw_input('TB: ') |
| exceptKeyboardInterrupt: |
| print'\n[Interrupted]' |
| break |
| exceptEOFError: |
| print'\n[EOF]' |
| break |
| cmd= string.strip(line) |
| if cmd: |
| if cmd=='quit': |
| break |
| elif cmd=='list': |
| browserlist(tb) |
| elif cmd=='up': |
| if ptr-1>=0: ptr= ptr-1 |
| else:print'Bottom of stack.' |
| elif cmd=='down': |
| if ptr+1< len(tblist): ptr= ptr+1 |
| else:print'Top of stack.' |
| elif cmd=='locals': |
| printsymbols(tb.tb_frame.f_locals) |
| elif cmd=='globals': |
| printsymbols(tb.tb_frame.f_globals) |
| elif cmdin('?','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 iin range(first, last+1): |
| if i== lineno: prefix='***'+ string.rjust(`i`,4)+':' |
| else: prefix= string.rjust(`i`,7)+':' |
| line= linecache.getline(filename, i) |
| if line[-1:]=='\n': line= line[:-1] |
| print prefix+ line |
| |
| def browserexec(tb, cmd): |
| locals= tb.tb_frame.f_locals |
| globals= tb.tb_frame.f_globals |
| try: |
| exec(cmd+'\n', globals, locals) |
| except: |
| print'*** Exception:', |
| print sys.exc_type, |
| if sys.exc_value<>None: |
| print':', sys.exc_value, |
| 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_localsisnot 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) |
| if line: |
| info= info+': '+ string.strip(line) |
| print info |
| |
| def printsymbols(d): |
| keys= d.keys() |
| keys.sort() |
| for namein keys: |
| print' '+ string.ljust(name,12)+':', |
| printobject(d[name],4) |
| print |
| |
| def printobject(v, maxlevel): |
| if v==None: |
| print'None', |
| elif type(v)in(type(0), type(0.0)): |
| print v, |
| elif type(v)== type(''): |
| if len(v)>20: |
| print`v[:17]+'...'`, |
| else: |
| print`v`, |
| elif type(v)== type(()): |
| print'(', |
| printlist(v, maxlevel) |
| print')', |
| elif type(v)== type([]): |
| print'[', |
| printlist(v, maxlevel) |
| print']', |
| elif type(v)== type({}): |
| print'{', |
| printdict(v, maxlevel) |
| print'}', |
| else: |
| print v, |
| |
| def printlist(v, maxlevel): |
| n= len(v) |
| if n==0:return |
| if maxlevel<=0: |
| print'...', |
| return |
| for iin 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) |
| if n==0:return |
| if maxlevel<=0: |
| print'...', |
| return |
| keys.sort() |
| for iin range(min(6, n)): |
| key= keys[i] |
| print`key`+':', |
| printobject(v[key], maxlevel-1) |
| if i+1< n:print',', |
| if n>6:print'...', |