python (3.11.7)

(root)/
lib/
python3.11/
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          # TODO return sorted(self.object)
      97          keys = list(self.object)
      98          try:
      99              keys.sort()
     100          except:
     101              pass
     102          return keys
     103  
     104  dispatch = {
     105      int: AtomicObjectTreeItem,
     106      float: AtomicObjectTreeItem,
     107      str: AtomicObjectTreeItem,
     108      tuple: SequenceTreeItem,
     109      list: SequenceTreeItem,
     110      dict: DictTreeItem,
     111      type: ClassTreeItem,
     112  }
     113  
     114  def make_objecttreeitem(labeltext, object, setfunction=None):
     115      t = type(object)
     116      if t in dispatch:
     117          c = dispatch[t]
     118      else:
     119          c = ObjectTreeItem
     120      return c(labeltext, object, setfunction)
     121  
     122  
     123  def _debug_object_browser(parent):  # htest #
     124      import sys
     125      from tkinter import Toplevel
     126      top = Toplevel(parent)
     127      top.title("Test debug object browser")
     128      x, y = map(int, parent.geometry().split('+')[1:])
     129      top.geometry("+%d+%d" % (x + 100, y + 175))
     130      top.configure(bd=0, bg="yellow")
     131      top.focus_set()
     132      sc = ScrolledCanvas(top, bg="white", highlightthickness=0, takefocus=1)
     133      sc.frame.pack(expand=1, fill="both")
     134      item = make_objecttreeitem("sys", sys)
     135      node = TreeNode(sc.canvas, None, item)
     136      node.update()
     137  
     138  
     139  if __name__ == '__main__':
     140      from unittest import main
     141      main('idlelib.idle_test.test_debugobj', verbosity=2, exit=False)
     142  
     143      from idlelib.idle_test.htest import run
     144      run(_debug_object_browser)