- Notifications
You must be signed in to change notification settings - Fork 31.8k
/
Copy pathstackviewer.py
148 lines (125 loc) · 4.21 KB
/
stackviewer.py
1
2
3
4
5
6
7
8
9
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
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
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
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
importos
importsys
importlinecache
importre
importtkinterastk
fromidlelib.treeimportTreeNode, TreeItem, ScrolledCanvas
fromidlelib.debugobjimportObjectTreeItem, make_objecttreeitem
defStackBrowser(root, flist=None, tb=None, top=None):
iftopisNone:
top=tk.Toplevel(root)
sc=ScrolledCanvas(top, bg="white", highlightthickness=0)
sc.frame.pack(expand=1, fill="both")
item=StackTreeItem(flist, tb)
node=TreeNode(sc.canvas, None, item)
node.expand()
classStackTreeItem(TreeItem):
def__init__(self, flist=None, tb=None):
self.flist=flist
self.stack=self.get_stack(tb)
self.text=self.get_exception()
defget_stack(self, tb):
iftbisNone:
tb=sys.last_traceback
stack= []
iftbandtb.tb_frameisNone:
tb=tb.tb_next
whiletbisnotNone:
stack.append((tb.tb_frame, tb.tb_lineno))
tb=tb.tb_next
returnstack
defget_exception(self):
type=sys.last_type
value=sys.last_value
ifhasattr(type, "__name__"):
type=type.__name__
s=str(type)
ifvalueisnotNone:
s=s+": "+str(value)
returns
defGetText(self):
returnself.text
defGetSubList(self):
sublist= []
forinfoinself.stack:
item=FrameTreeItem(info, self.flist)
sublist.append(item)
returnsublist
classFrameTreeItem(TreeItem):
def__init__(self, info, flist):
self.info=info
self.flist=flist
defGetText(self):
frame, lineno=self.info
try:
modname=frame.f_globals["__name__"]
except:
modname="?"
code=frame.f_code
filename=code.co_filename
funcname=code.co_name
sourceline=linecache.getline(filename, lineno)
sourceline=sourceline.strip()
iffuncnamein ("?", "", None):
item="%s, line %d: %s"% (modname, lineno, sourceline)
else:
item="%s.%s(...), line %d: %s"% (modname, funcname,
lineno, sourceline)
returnitem
defGetSubList(self):
frame, lineno=self.info
sublist= []
ifframe.f_globalsisnotframe.f_locals:
item=VariablesTreeItem("<locals>", frame.f_locals, self.flist)
sublist.append(item)
item=VariablesTreeItem("<globals>", frame.f_globals, self.flist)
sublist.append(item)
returnsublist
defOnDoubleClick(self):
ifself.flist:
frame, lineno=self.info
filename=frame.f_code.co_filename
ifos.path.isfile(filename):
self.flist.gotofileline(filename, lineno)
classVariablesTreeItem(ObjectTreeItem):
defGetText(self):
returnself.labeltext
defGetLabelText(self):
returnNone
defIsExpandable(self):
returnlen(self.object) >0
defGetSubList(self):
sublist= []
forkeyinself.object.keys():
try:
value=self.object[key]
exceptKeyError:
continue
defsetfunction(value, key=key, object=self.object):
object[key] =value
item=make_objecttreeitem(key+" =", value, setfunction)
sublist.append(item)
returnsublist
def_stack_viewer(parent): # htest #
fromidlelib.pyshellimportPyShellFileList
top=tk.Toplevel(parent)
top.title("Test StackViewer")
x, y=map(int, parent.geometry().split('+')[1:])
top.geometry("+%d+%d"% (x+50, y+175))
flist=PyShellFileList(top)
try: # to obtain a traceback object
intentional_name_error
exceptNameError:
exc_type, exc_value, exc_tb=sys.exc_info()
# inject stack trace to sys
sys.last_type=exc_type
sys.last_value=exc_value
sys.last_traceback=exc_tb
StackBrowser(top, flist=flist, top=top, tb=exc_tb)
# restore sys to original state
delsys.last_type
delsys.last_value
delsys.last_traceback
if__name__=='__main__':
fromidlelib.idle_test.htestimportrun
run(_stack_viewer)