(root)/
Python-3.12.0/
Lib/
idlelib/
debugobj.py
       1  # 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
      11  from reprlib import Repr
      12  
      13  from idlelib.tree import TreeItem, TreeNode, ScrolledCanvas
      14  
      15  myrepr = Repr()
      16  myrepr.maxstring = 100
      17  myrepr.maxother = 100
      18  
      19  class ESC[4;38;5;81mObjectTreeItem(ESC[4;38;5;149mTreeItem):
      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  
      59  class ESC[4;38;5;81mClassTreeItem(ESC[4;38;5;149mObjectTreeItem):
      60      def IsExpandable(self):
      61          return True
      62      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  
      72  class ESC[4;38;5;81mAtomicObjectTreeItem(ESC[4;38;5;149mObjectTreeItem):
      73      def IsExpandable(self):
      74          return False
      75  
      76  class ESC[4;38;5;81mSequenceTreeItem(ESC[4;38;5;149mObjectTreeItem):
      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
      90              item = make_objecttreeitem(f"{key!r}:", value, setfunction)
      91              sublist.append(item)
      92          return sublist
      93  
      94  class ESC[4;38;5;81mDictTreeItem(ESC[4;38;5;149mSequenceTreeItem):
      95      def keys(self):
      96          keys = list(self.object.keys())
      97          try:
      98              keys.sort()
      99          except:
     100              pass
     101          return keys
     102  
     103  dispatch = {
     104      int: AtomicObjectTreeItem,
     105      float: AtomicObjectTreeItem,
     106      str: AtomicObjectTreeItem,
     107      tuple: SequenceTreeItem,
     108      list: SequenceTreeItem,
     109      dict: DictTreeItem,
     110      type: ClassTreeItem,
     111  }
     112  
     113  def make_objecttreeitem(labeltext, object, setfunction=None):
     114      t = type(object)
     115      if t in dispatch:
     116          c = dispatch[t]
     117      else:
     118          c = ObjectTreeItem
     119      return c(labeltext, object, setfunction)
     120  
     121  
     122  def _object_browser(parent):  # htest #
     123      import sys
     124      from tkinter import Toplevel
     125      top = Toplevel(parent)
     126      top.title("Test debug object browser")
     127      x, y = map(int, parent.geometry().split('+')[1:])
     128      top.geometry("+%d+%d" % (x + 100, y + 175))
     129      top.configure(bd=0, bg="yellow")
     130      top.focus_set()
     131      sc = ScrolledCanvas(top, bg="white", highlightthickness=0, takefocus=1)
     132      sc.frame.pack(expand=1, fill="both")
     133      item = make_objecttreeitem("sys", sys)
     134      node = TreeNode(sc.canvas, None, item)
     135      node.update()
     136  
     137  if __name__ == '__main__':
     138      from unittest import main
     139      main('idlelib.idle_test.test_debugobj', verbosity=2, exit=False)
     140  
     141      from idlelib.idle_test.htest import run
     142      run(_object_browser)