• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1"""Define tree items for debug stackviewer, which is only user.
2"""
3# XXX TO DO:
4# - popup menu
5# - support partial or total redisplay
6# - more doc strings
7# - tooltips
8
9# object browser
10
11# XXX TO DO:
12# - for classes/modules, add "open source" to object browser
13from reprlib import Repr
14
15from idlelib.tree import TreeItem, TreeNode, ScrolledCanvas
16
17myrepr = Repr()
18myrepr.maxstring = 100
19myrepr.maxother = 100
20
21class ObjectTreeItem(TreeItem):
22    def __init__(self, labeltext, object_, setfunction=None):
23        self.labeltext = labeltext
24        self.object = object_
25        self.setfunction = setfunction
26    def GetLabelText(self):
27        return self.labeltext
28    def GetText(self):
29        return myrepr.repr(self.object)
30    def GetIconName(self):
31        if not self.IsExpandable():
32            return "python"
33    def IsEditable(self):
34        return self.setfunction is not None
35    def SetText(self, text):
36        try:
37            value = eval(text)
38            self.setfunction(value)
39        except:
40            pass
41        else:
42            self.object = value
43    def IsExpandable(self):
44        return not not dir(self.object)
45    def GetSubList(self):
46        keys = dir(self.object)
47        sublist = []
48        for key in keys:
49            try:
50                value = getattr(self.object, key)
51            except AttributeError:
52                continue
53            item = make_objecttreeitem(
54                str(key) + " =",
55                value,
56                lambda value, key=key, object_=self.object:
57                    setattr(object_, key, value))
58            sublist.append(item)
59        return sublist
60
61class ClassTreeItem(ObjectTreeItem):
62    def IsExpandable(self):
63        return True
64    def GetSubList(self):
65        sublist = ObjectTreeItem.GetSubList(self)
66        if len(self.object.__bases__) == 1:
67            item = make_objecttreeitem("__bases__[0] =",
68                self.object.__bases__[0])
69        else:
70            item = make_objecttreeitem("__bases__ =", self.object.__bases__)
71        sublist.insert(0, item)
72        return sublist
73
74class AtomicObjectTreeItem(ObjectTreeItem):
75    def IsExpandable(self):
76        return False
77
78class SequenceTreeItem(ObjectTreeItem):
79    def IsExpandable(self):
80        return len(self.object) > 0
81    def keys(self):
82        return range(len(self.object))
83    def GetSubList(self):
84        sublist = []
85        for key in self.keys():
86            try:
87                value = self.object[key]
88            except KeyError:
89                continue
90            def setfunction(value, key=key, object_=self.object):
91                object_[key] = value
92            item = make_objecttreeitem(f"{key!r}:", value, setfunction)
93            sublist.append(item)
94        return sublist
95
96class DictTreeItem(SequenceTreeItem):
97    def keys(self):
98        # TODO return sorted(self.object)
99        keys = list(self.object)
100        try:
101            keys.sort()
102        except:
103            pass
104        return keys
105
106dispatch = {
107    int: AtomicObjectTreeItem,
108    float: AtomicObjectTreeItem,
109    str: AtomicObjectTreeItem,
110    tuple: SequenceTreeItem,
111    list: SequenceTreeItem,
112    dict: DictTreeItem,
113    type: ClassTreeItem,
114}
115
116def make_objecttreeitem(labeltext, object_, setfunction=None):
117    t = type(object_)
118    if t in dispatch:
119        c = dispatch[t]
120    else:
121        c = ObjectTreeItem
122    return c(labeltext, object_, setfunction)
123
124
125def _debug_object_browser(parent):  # htest #
126    import sys
127    from tkinter import Toplevel
128    top = Toplevel(parent)
129    top.title("Test debug object browser")
130    x, y = map(int, parent.geometry().split('+')[1:])
131    top.geometry("+%d+%d" % (x + 100, y + 175))
132    top.configure(bd=0, bg="yellow")
133    top.focus_set()
134    sc = ScrolledCanvas(top, bg="white", highlightthickness=0, takefocus=1)
135    sc.frame.pack(expand=1, fill="both")
136    item = make_objecttreeitem("sys", sys)
137    node = TreeNode(sc.canvas, None, item)
138    node.update()
139
140
141if __name__ == '__main__':
142    from unittest import main
143    main('idlelib.idle_test.test_debugobj', verbosity=2, exit=False)
144
145    from idlelib.idle_test.htest import run
146    run(_debug_object_browser)
147