1 import os 2 import sys 3 import linecache 4 5 from idlelib.TreeWidget import TreeNode, TreeItem, ScrolledCanvas 6 from idlelib.ObjectBrowser import ObjectTreeItem, make_objecttreeitem 7 8 def StackBrowser(root, flist=None, tb=None, top=None): 9 if top is None: 10 from Tkinter import Toplevel 11 top = Toplevel(root) 12 sc = ScrolledCanvas(top, bg="white", highlightthickness=0) 13 sc.frame.pack(expand=1, fill="both") 14 item = StackTreeItem(flist, tb) 15 node = TreeNode(sc.canvas, None, item) 16 node.expand() 17 18 class StackTreeItem(TreeItem): 19 20 def __init__(self, flist=None, tb=None): 21 self.flist = flist 22 self.stack = self.get_stack(tb) 23 self.text = self.get_exception() 24 25 def get_stack(self, tb): 26 if tb is None: 27 tb = sys.last_traceback 28 stack = [] 29 if tb and tb.tb_frame is None: 30 tb = tb.tb_next 31 while tb is not None: 32 stack.append((tb.tb_frame, tb.tb_lineno)) 33 tb = tb.tb_next 34 return stack 35 36 def get_exception(self): 37 type = sys.last_type 38 value = sys.last_value 39 if hasattr(type, "__name__"): 40 type = type.__name__ 41 s = str(type) 42 if value is not None: 43 s = s + ": " + str(value) 44 return s 45 46 def GetText(self): 47 return self.text 48 49 def GetSubList(self): 50 sublist = [] 51 for info in self.stack: 52 item = FrameTreeItem(info, self.flist) 53 sublist.append(item) 54 return sublist 55 56 class FrameTreeItem(TreeItem): 57 58 def __init__(self, info, flist): 59 self.info = info 60 self.flist = flist 61 62 def GetText(self): 63 frame, lineno = self.info 64 try: 65 modname = frame.f_globals["__name__"] 66 except: 67 modname = "?" 68 code = frame.f_code 69 filename = code.co_filename 70 funcname = code.co_name 71 sourceline = linecache.getline(filename, lineno) 72 sourceline = sourceline.strip() 73 if funcname in ("?", "", None): 74 item = "%s, line %d: %s" % (modname, lineno, sourceline) 75 else: 76 item = "%s.%s(...), line %d: %s" % (modname, funcname, 77 lineno, sourceline) 78 return item 79 80 def GetSubList(self): 81 frame, lineno = self.info 82 sublist = [] 83 if frame.f_globals is not frame.f_locals: 84 item = VariablesTreeItem("<locals>", frame.f_locals, self.flist) 85 sublist.append(item) 86 item = VariablesTreeItem("<globals>", frame.f_globals, self.flist) 87 sublist.append(item) 88 return sublist 89 90 def OnDoubleClick(self): 91 if self.flist: 92 frame, lineno = self.info 93 filename = frame.f_code.co_filename 94 if os.path.isfile(filename): 95 self.flist.gotofileline(filename, lineno) 96 97 class VariablesTreeItem(ObjectTreeItem): 98 99 def GetText(self): 100 return self.labeltext 101 102 def GetLabelText(self): 103 return None 104 105 def IsExpandable(self): 106 return len(self.object) > 0 107 108 def keys(self): 109 return self.object.keys() 110 111 def GetSubList(self): 112 sublist = [] 113 for key in self.keys(): 114 try: 115 value = self.object[key] 116 except KeyError: 117 continue 118 def setfunction(value, key=key, object=self.object): 119 object[key] = value 120 item = make_objecttreeitem(key + " =", value, setfunction) 121 sublist.append(item) 122 return sublist 123 124 125 def _test(): 126 try: 127 import testcode 128 reload(testcode) 129 except: 130 sys.last_type, sys.last_value, sys.last_traceback = sys.exc_info() 131 from Tkinter import Tk 132 root = Tk() 133 StackBrowser(None, top=root) 134 root.mainloop() 135 136 if __name__ == "__main__": 137 _test() 138