- Notifications
You must be signed in to change notification settings - Fork 31.8k
/
Copy pathstackviewer.py
134 lines (107 loc) · 3.92 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
# Rename to stackbrowser or possibly consolidate with browser.
importlinecache
importos
importtkinterastk
fromidlelib.debugobjimportObjectTreeItem, make_objecttreeitem
fromidlelib.treeimportTreeNode, TreeItem, ScrolledCanvas
defStackBrowser(root, exc, flist=None, top=None):
globalsc, item, node# For testing.
iftopisNone:
top=tk.Toplevel(root)
sc=ScrolledCanvas(top, bg="white", highlightthickness=0)
sc.frame.pack(expand=1, fill="both")
item=StackTreeItem(exc, flist)
node=TreeNode(sc.canvas, None, item)
node.expand()
classStackTreeItem(TreeItem):
def__init__(self, exc, flist=None):
self.flist=flist
self.stack=self.get_stack(NoneifexcisNoneelseexc.__traceback__)
self.text=f"{type(exc).__name__}: {str(exc)}"
defget_stack(self, tb):
stack= []
iftbandtb.tb_frameisNone:
tb=tb.tb_next
whiletbisnotNone:
stack.append((tb.tb_frame, tb.tb_lineno))
tb=tb.tb_next
returnstack
defGetText(self): # Titlecase names are overrides.
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(): # self.object not necessarily dict.
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_stackbrowser(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
exceptNameErrorase:
StackBrowser(top, e, flist=flist, top=top)
if__name__=='__main__':
fromunittestimportmain
main('idlelib.idle_test.test_stackviewer', verbosity=2, exit=False)
fromidlelib.idle_test.htestimportrun
run(_stackbrowser)