blob: 5a4c99788420357221cf4ad0372a41e4ccd6a08d [file] [log] [blame]
David Scherer7aced172000-08-15 01:13:23 +00001# XXX TO DO:
2# - popup menu
3# - support partial or total redisplay
4# - more doc strings
5# - tooltips
6
7# object browser
8
9# XXX TO DO:
10# - for classes/modules, add "open source" to object browser
Terry Jan Reedybfbaa6b2016-08-31 00:50:55 -040011from reprlib import Repr
David Scherer7aced172000-08-15 01:13:23 +000012
Terry Jan Reedy6fa5bdc2016-05-28 13:22:31 -040013from idlelib.tree import TreeItem, TreeNode, ScrolledCanvas
David Scherer7aced172000-08-15 01:13:23 +000014
David Scherer7aced172000-08-15 01:13:23 +000015myrepr = Repr()
16myrepr.maxstring = 100
17myrepr.maxother = 100
18
19class ObjectTreeItem(TreeItem):
20 def __init__(self, labeltext, object, setfunction=None):
21 self.labeltext = labeltext
22 self.object = object
23 self.setfunction = setfunction
24 def GetLabelText(self):
25 return self.labeltext
26 def GetText(self):
27 return myrepr.repr(self.object)
28 def GetIconName(self):
29 if not self.IsExpandable():
30 return "python"
31 def IsEditable(self):
32 return self.setfunction is not None
33 def SetText(self, text):
34 try:
35 value = eval(text)
36 self.setfunction(value)
37 except:
38 pass
39 else:
40 self.object = value
41 def IsExpandable(self):
42 return not not dir(self.object)
43 def GetSubList(self):
44 keys = dir(self.object)
45 sublist = []
46 for key in keys:
47 try:
48 value = getattr(self.object, key)
49 except AttributeError:
50 continue
51 item = make_objecttreeitem(
52 str(key) + " =",
53 value,
54 lambda value, key=key, object=self.object:
55 setattr(object, key, value))
56 sublist.append(item)
57 return sublist
58
David Scherer7aced172000-08-15 01:13:23 +000059class ClassTreeItem(ObjectTreeItem):
60 def IsExpandable(self):
Kurt B. Kaiser33931ef2002-09-16 22:16:05 +000061 return True
David Scherer7aced172000-08-15 01:13:23 +000062 def GetSubList(self):
63 sublist = ObjectTreeItem.GetSubList(self)
64 if len(self.object.__bases__) == 1:
65 item = make_objecttreeitem("__bases__[0] =",
66 self.object.__bases__[0])
67 else:
68 item = make_objecttreeitem("__bases__ =", self.object.__bases__)
69 sublist.insert(0, item)
70 return sublist
71
72class AtomicObjectTreeItem(ObjectTreeItem):
73 def IsExpandable(self):
Terry Jan Reedyee5ef302018-06-15 18:20:55 -040074 return False
David Scherer7aced172000-08-15 01:13:23 +000075
76class SequenceTreeItem(ObjectTreeItem):
77 def IsExpandable(self):
78 return len(self.object) > 0
79 def keys(self):
80 return range(len(self.object))
81 def GetSubList(self):
82 sublist = []
83 for key in self.keys():
84 try:
85 value = self.object[key]
86 except KeyError:
87 continue
88 def setfunction(value, key=key, object=self.object):
89 object[key] = value
Walter Dörwald70a6b492004-02-12 17:35:32 +000090 item = make_objecttreeitem("%r:" % (key,), value, setfunction)
David Scherer7aced172000-08-15 01:13:23 +000091 sublist.append(item)
92 return sublist
93
94class DictTreeItem(SequenceTreeItem):
95 def keys(self):
Kurt B. Kaisere0712772007-08-23 05:25:55 +000096 keys = list(self.object.keys())
David Scherer7aced172000-08-15 01:13:23 +000097 try:
98 keys.sort()
99 except:
100 pass
101 return keys
102
David Scherer7aced172000-08-15 01:13:23 +0000103dispatch = {
Guido van Rossum13257902007-06-07 23:15:56 +0000104 int: AtomicObjectTreeItem,
105 float: AtomicObjectTreeItem,
106 str: AtomicObjectTreeItem,
107 tuple: SequenceTreeItem,
108 list: SequenceTreeItem,
109 dict: DictTreeItem,
110 type: ClassTreeItem,
David Scherer7aced172000-08-15 01:13:23 +0000111}
112
113def make_objecttreeitem(labeltext, object, setfunction=None):
114 t = type(object)
Guido van Rossum811c4e02006-08-22 15:45:46 +0000115 if t in dispatch:
David Scherer7aced172000-08-15 01:13:23 +0000116 c = dispatch[t]
117 else:
118 c = ObjectTreeItem
119 return c(labeltext, object, setfunction)
120
David Scherer7aced172000-08-15 01:13:23 +0000121
Terry Jan Reedyb60adc52016-06-21 18:41:38 -0400122def _object_browser(parent): # htest #
David Scherer7aced172000-08-15 01:13:23 +0000123 import sys
Terry Jan Reedyb60adc52016-06-21 18:41:38 -0400124 from tkinter import Toplevel
125 top = Toplevel(parent)
126 top.title("Test debug object browser")
Terry Jan Reedya7480322016-07-10 17:28:10 -0400127 x, y = map(int, parent.geometry().split('+')[1:])
128 top.geometry("+%d+%d" % (x + 100, y + 175))
Terry Jan Reedyb60adc52016-06-21 18:41:38 -0400129 top.configure(bd=0, bg="yellow")
130 top.focus_set()
131 sc = ScrolledCanvas(top, bg="white", highlightthickness=0, takefocus=1)
David Scherer7aced172000-08-15 01:13:23 +0000132 sc.frame.pack(expand=1, fill="both")
133 item = make_objecttreeitem("sys", sys)
134 node = TreeNode(sc.canvas, None, item)
Kurt B. Kaiser6a945a52001-07-13 17:57:37 +0000135 node.update()
David Scherer7aced172000-08-15 01:13:23 +0000136
137if __name__ == '__main__':
Terry Jan Reedyee5ef302018-06-15 18:20:55 -0400138 from unittest import main
139 main('idlelib.idle_test.test_debugobj', verbosity=2, exit=False)
140
Terry Jan Reedy1b392ff2014-05-24 18:48:18 -0400141 from idlelib.idle_test.htest import run
142 run(_object_browser)