Commit | Line | Data |
---|---|---|
920dae64 AT |
1 | import os |
2 | import sys | |
3 | import linecache | |
4 | ||
5 | from TreeWidget import TreeNode, TreeItem, ScrolledCanvas | |
6 | from 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() |