xref: /third_party/python/Lib/idlelib/debugobj.py (revision 7db96d56)
17db96d56Sopenharmony_ci# XXX TO DO:
27db96d56Sopenharmony_ci# - popup menu
37db96d56Sopenharmony_ci# - support partial or total redisplay
47db96d56Sopenharmony_ci# - more doc strings
57db96d56Sopenharmony_ci# - tooltips
67db96d56Sopenharmony_ci
77db96d56Sopenharmony_ci# object browser
87db96d56Sopenharmony_ci
97db96d56Sopenharmony_ci# XXX TO DO:
107db96d56Sopenharmony_ci# - for classes/modules, add "open source" to object browser
117db96d56Sopenharmony_cifrom reprlib import Repr
127db96d56Sopenharmony_ci
137db96d56Sopenharmony_cifrom idlelib.tree import TreeItem, TreeNode, ScrolledCanvas
147db96d56Sopenharmony_ci
157db96d56Sopenharmony_cimyrepr = Repr()
167db96d56Sopenharmony_cimyrepr.maxstring = 100
177db96d56Sopenharmony_cimyrepr.maxother = 100
187db96d56Sopenharmony_ci
197db96d56Sopenharmony_ciclass ObjectTreeItem(TreeItem):
207db96d56Sopenharmony_ci    def __init__(self, labeltext, object, setfunction=None):
217db96d56Sopenharmony_ci        self.labeltext = labeltext
227db96d56Sopenharmony_ci        self.object = object
237db96d56Sopenharmony_ci        self.setfunction = setfunction
247db96d56Sopenharmony_ci    def GetLabelText(self):
257db96d56Sopenharmony_ci        return self.labeltext
267db96d56Sopenharmony_ci    def GetText(self):
277db96d56Sopenharmony_ci        return myrepr.repr(self.object)
287db96d56Sopenharmony_ci    def GetIconName(self):
297db96d56Sopenharmony_ci        if not self.IsExpandable():
307db96d56Sopenharmony_ci            return "python"
317db96d56Sopenharmony_ci    def IsEditable(self):
327db96d56Sopenharmony_ci        return self.setfunction is not None
337db96d56Sopenharmony_ci    def SetText(self, text):
347db96d56Sopenharmony_ci        try:
357db96d56Sopenharmony_ci            value = eval(text)
367db96d56Sopenharmony_ci            self.setfunction(value)
377db96d56Sopenharmony_ci        except:
387db96d56Sopenharmony_ci            pass
397db96d56Sopenharmony_ci        else:
407db96d56Sopenharmony_ci            self.object = value
417db96d56Sopenharmony_ci    def IsExpandable(self):
427db96d56Sopenharmony_ci        return not not dir(self.object)
437db96d56Sopenharmony_ci    def GetSubList(self):
447db96d56Sopenharmony_ci        keys = dir(self.object)
457db96d56Sopenharmony_ci        sublist = []
467db96d56Sopenharmony_ci        for key in keys:
477db96d56Sopenharmony_ci            try:
487db96d56Sopenharmony_ci                value = getattr(self.object, key)
497db96d56Sopenharmony_ci            except AttributeError:
507db96d56Sopenharmony_ci                continue
517db96d56Sopenharmony_ci            item = make_objecttreeitem(
527db96d56Sopenharmony_ci                str(key) + " =",
537db96d56Sopenharmony_ci                value,
547db96d56Sopenharmony_ci                lambda value, key=key, object=self.object:
557db96d56Sopenharmony_ci                    setattr(object, key, value))
567db96d56Sopenharmony_ci            sublist.append(item)
577db96d56Sopenharmony_ci        return sublist
587db96d56Sopenharmony_ci
597db96d56Sopenharmony_ciclass ClassTreeItem(ObjectTreeItem):
607db96d56Sopenharmony_ci    def IsExpandable(self):
617db96d56Sopenharmony_ci        return True
627db96d56Sopenharmony_ci    def GetSubList(self):
637db96d56Sopenharmony_ci        sublist = ObjectTreeItem.GetSubList(self)
647db96d56Sopenharmony_ci        if len(self.object.__bases__) == 1:
657db96d56Sopenharmony_ci            item = make_objecttreeitem("__bases__[0] =",
667db96d56Sopenharmony_ci                self.object.__bases__[0])
677db96d56Sopenharmony_ci        else:
687db96d56Sopenharmony_ci            item = make_objecttreeitem("__bases__ =", self.object.__bases__)
697db96d56Sopenharmony_ci        sublist.insert(0, item)
707db96d56Sopenharmony_ci        return sublist
717db96d56Sopenharmony_ci
727db96d56Sopenharmony_ciclass AtomicObjectTreeItem(ObjectTreeItem):
737db96d56Sopenharmony_ci    def IsExpandable(self):
747db96d56Sopenharmony_ci        return False
757db96d56Sopenharmony_ci
767db96d56Sopenharmony_ciclass SequenceTreeItem(ObjectTreeItem):
777db96d56Sopenharmony_ci    def IsExpandable(self):
787db96d56Sopenharmony_ci        return len(self.object) > 0
797db96d56Sopenharmony_ci    def keys(self):
807db96d56Sopenharmony_ci        return range(len(self.object))
817db96d56Sopenharmony_ci    def GetSubList(self):
827db96d56Sopenharmony_ci        sublist = []
837db96d56Sopenharmony_ci        for key in self.keys():
847db96d56Sopenharmony_ci            try:
857db96d56Sopenharmony_ci                value = self.object[key]
867db96d56Sopenharmony_ci            except KeyError:
877db96d56Sopenharmony_ci                continue
887db96d56Sopenharmony_ci            def setfunction(value, key=key, object=self.object):
897db96d56Sopenharmony_ci                object[key] = value
907db96d56Sopenharmony_ci            item = make_objecttreeitem(f"{key!r}:", value, setfunction)
917db96d56Sopenharmony_ci            sublist.append(item)
927db96d56Sopenharmony_ci        return sublist
937db96d56Sopenharmony_ci
947db96d56Sopenharmony_ciclass DictTreeItem(SequenceTreeItem):
957db96d56Sopenharmony_ci    def keys(self):
967db96d56Sopenharmony_ci        keys = list(self.object.keys())
977db96d56Sopenharmony_ci        try:
987db96d56Sopenharmony_ci            keys.sort()
997db96d56Sopenharmony_ci        except:
1007db96d56Sopenharmony_ci            pass
1017db96d56Sopenharmony_ci        return keys
1027db96d56Sopenharmony_ci
1037db96d56Sopenharmony_cidispatch = {
1047db96d56Sopenharmony_ci    int: AtomicObjectTreeItem,
1057db96d56Sopenharmony_ci    float: AtomicObjectTreeItem,
1067db96d56Sopenharmony_ci    str: AtomicObjectTreeItem,
1077db96d56Sopenharmony_ci    tuple: SequenceTreeItem,
1087db96d56Sopenharmony_ci    list: SequenceTreeItem,
1097db96d56Sopenharmony_ci    dict: DictTreeItem,
1107db96d56Sopenharmony_ci    type: ClassTreeItem,
1117db96d56Sopenharmony_ci}
1127db96d56Sopenharmony_ci
1137db96d56Sopenharmony_cidef make_objecttreeitem(labeltext, object, setfunction=None):
1147db96d56Sopenharmony_ci    t = type(object)
1157db96d56Sopenharmony_ci    if t in dispatch:
1167db96d56Sopenharmony_ci        c = dispatch[t]
1177db96d56Sopenharmony_ci    else:
1187db96d56Sopenharmony_ci        c = ObjectTreeItem
1197db96d56Sopenharmony_ci    return c(labeltext, object, setfunction)
1207db96d56Sopenharmony_ci
1217db96d56Sopenharmony_ci
1227db96d56Sopenharmony_cidef _object_browser(parent):  # htest #
1237db96d56Sopenharmony_ci    import sys
1247db96d56Sopenharmony_ci    from tkinter import Toplevel
1257db96d56Sopenharmony_ci    top = Toplevel(parent)
1267db96d56Sopenharmony_ci    top.title("Test debug object browser")
1277db96d56Sopenharmony_ci    x, y = map(int, parent.geometry().split('+')[1:])
1287db96d56Sopenharmony_ci    top.geometry("+%d+%d" % (x + 100, y + 175))
1297db96d56Sopenharmony_ci    top.configure(bd=0, bg="yellow")
1307db96d56Sopenharmony_ci    top.focus_set()
1317db96d56Sopenharmony_ci    sc = ScrolledCanvas(top, bg="white", highlightthickness=0, takefocus=1)
1327db96d56Sopenharmony_ci    sc.frame.pack(expand=1, fill="both")
1337db96d56Sopenharmony_ci    item = make_objecttreeitem("sys", sys)
1347db96d56Sopenharmony_ci    node = TreeNode(sc.canvas, None, item)
1357db96d56Sopenharmony_ci    node.update()
1367db96d56Sopenharmony_ci
1377db96d56Sopenharmony_ciif __name__ == '__main__':
1387db96d56Sopenharmony_ci    from unittest import main
1397db96d56Sopenharmony_ci    main('idlelib.idle_test.test_debugobj', verbosity=2, exit=False)
1407db96d56Sopenharmony_ci
1417db96d56Sopenharmony_ci    from idlelib.idle_test.htest import run
1427db96d56Sopenharmony_ci    run(_object_browser)
143