Coverage for stackviewer.py: 18%

122 statements  

« prev     ^ index     » next       coverage.py v7.2.5, created at 2023-05-11 13:22 -0700

1import linecache 

2import os 

3import sys 

4 

5import tkinter as tk 

6 

7from idlelib.debugobj import ObjectTreeItem, make_objecttreeitem 

8from idlelib.tree import TreeNode, TreeItem, ScrolledCanvas 

9 

10def StackBrowser(root, flist=None, tb=None, top=None): 

11 global sc, item, node # For testing. 

12 if top is None: 

13 top = tk.Toplevel(root) 

14 sc = ScrolledCanvas(top, bg="white", highlightthickness=0) 

15 sc.frame.pack(expand=1, fill="both") 

16 item = StackTreeItem(flist, tb) 

17 node = TreeNode(sc.canvas, None, item) 

18 node.expand() 

19 

20 

21class StackTreeItem(TreeItem): 

22 

23 def __init__(self, flist=None, tb=None): 

24 self.flist = flist 

25 self.stack = self.get_stack(tb) 

26 self.text = self.get_exception() 

27 

28 def get_stack(self, tb): 

29 if tb is None: 

30 tb = sys.last_traceback 

31 stack = [] 

32 if tb and tb.tb_frame is None: 

33 tb = tb.tb_next 

34 while tb is not None: 

35 stack.append((tb.tb_frame, tb.tb_lineno)) 

36 tb = tb.tb_next 

37 return stack 

38 

39 def get_exception(self): 

40 type = sys.last_type 

41 value = sys.last_value 

42 if hasattr(type, "__name__"): 

43 type = type.__name__ 

44 s = str(type) 

45 if value is not None: 

46 s = s + ": " + str(value) 

47 return s 

48 

49 def GetText(self): 

50 return self.text 

51 

52 def GetSubList(self): 

53 sublist = [] 

54 for info in self.stack: 

55 item = FrameTreeItem(info, self.flist) 

56 sublist.append(item) 

57 return sublist 

58 

59 

60class FrameTreeItem(TreeItem): 

61 

62 def __init__(self, info, flist): 

63 self.info = info 

64 self.flist = flist 

65 

66 def GetText(self): 

67 frame, lineno = self.info 

68 try: 

69 modname = frame.f_globals["__name__"] 

70 except: 

71 modname = "?" 

72 code = frame.f_code 

73 filename = code.co_filename 

74 funcname = code.co_name 

75 sourceline = linecache.getline(filename, lineno) 

76 sourceline = sourceline.strip() 

77 if funcname in ("?", "", None): 

78 item = "%s, line %d: %s" % (modname, lineno, sourceline) 

79 else: 

80 item = "%s.%s(...), line %d: %s" % (modname, funcname, 

81 lineno, sourceline) 

82 return item 

83 

84 def GetSubList(self): 

85 frame, lineno = self.info 

86 sublist = [] 

87 if frame.f_globals is not frame.f_locals: 

88 item = VariablesTreeItem("<locals>", frame.f_locals, self.flist) 

89 sublist.append(item) 

90 item = VariablesTreeItem("<globals>", frame.f_globals, self.flist) 

91 sublist.append(item) 

92 return sublist 

93 

94 def OnDoubleClick(self): 

95 if self.flist: 

96 frame, lineno = self.info 

97 filename = frame.f_code.co_filename 

98 if os.path.isfile(filename): 

99 self.flist.gotofileline(filename, lineno) 

100 

101 

102class VariablesTreeItem(ObjectTreeItem): 

103 

104 def GetText(self): 

105 return self.labeltext 

106 

107 def GetLabelText(self): 

108 return None 

109 

110 def IsExpandable(self): 

111 return len(self.object) > 0 

112 

113 def GetSubList(self): 

114 sublist = [] 

115 for key in self.object.keys(): 

116 try: 

117 value = self.object[key] 

118 except KeyError: 

119 continue 

120 def setfunction(value, key=key, object=self.object): 

121 object[key] = value 

122 item = make_objecttreeitem(key + " =", value, setfunction) 

123 sublist.append(item) 

124 return sublist 

125 

126 

127def _stack_viewer(parent): # htest # 

128 from idlelib.pyshell import PyShellFileList 

129 top = tk.Toplevel(parent) 

130 top.title("Test StackViewer") 

131 x, y = map(int, parent.geometry().split('+')[1:]) 

132 top.geometry("+%d+%d" % (x + 50, y + 175)) 

133 flist = PyShellFileList(top) 

134 try: # to obtain a traceback object 

135 intentional_name_error 

136 except NameError: 

137 exc_type, exc_value, exc_tb = sys.exc_info() 

138 # inject stack trace to sys 

139 sys.last_type = exc_type 

140 sys.last_value = exc_value 

141 sys.last_traceback = exc_tb 

142 

143 StackBrowser(top, flist=flist, top=top, tb=exc_tb) 

144 

145 # restore sys to original state 

146 del sys.last_type 

147 del sys.last_value 

148 del sys.last_traceback 

149 

150if __name__ == '__main__': 150 ↛ 151line 150 didn't jump to line 151, because the condition on line 150 was never true

151 from unittest import main 

152 main('idlelib.idle_test.test_stackviewer', verbosity=2, exit=False) 

153 

154 from idlelib.idle_test.htest import run 

155 run(_stack_viewer)