(root)/
Python-3.12.0/
Lib/
idlelib/
stackviewer.py
       1  import linecache
       2  import os
       3  
       4  import tkinter as tk
       5  
       6  from idlelib.debugobj import ObjectTreeItem, make_objecttreeitem
       7  from idlelib.tree import TreeNode, TreeItem, ScrolledCanvas
       8  
       9  def StackBrowser(root, exc, flist=None, top=None):
      10      global sc, item, node  # For testing.
      11      if top is None:
      12          top = tk.Toplevel(root)
      13      sc = ScrolledCanvas(top, bg="white", highlightthickness=0)
      14      sc.frame.pack(expand=1, fill="both")
      15      item = StackTreeItem(exc, flist)
      16      node = TreeNode(sc.canvas, None, item)
      17      node.expand()
      18  
      19  
      20  class ESC[4;38;5;81mStackTreeItem(ESC[4;38;5;149mTreeItem):
      21  
      22      def __init__(self, exc, flist=None):
      23          self.flist = flist
      24          self.stack = self.get_stack(None if exc is None else exc.__traceback__)
      25          self.text = f"{type(exc).__name__}: {str(exc)}"
      26  
      27      def get_stack(self, tb):
      28          stack = []
      29          if tb and tb.tb_frame is None:
      30              tb = tb.tb_next
      31          while tb is not None:
      32              stack.append((tb.tb_frame, tb.tb_lineno))
      33              tb = tb.tb_next
      34          return stack
      35  
      36      def GetText(self):  # Titlecase names are overrides.
      37          return self.text
      38  
      39      def GetSubList(self):
      40          sublist = []
      41          for info in self.stack:
      42              item = FrameTreeItem(info, self.flist)
      43              sublist.append(item)
      44          return sublist
      45  
      46  
      47  class ESC[4;38;5;81mFrameTreeItem(ESC[4;38;5;149mTreeItem):
      48  
      49      def __init__(self, info, flist):
      50          self.info = info
      51          self.flist = flist
      52  
      53      def GetText(self):
      54          frame, lineno = self.info
      55          try:
      56              modname = frame.f_globals["__name__"]
      57          except:
      58              modname = "?"
      59          code = frame.f_code
      60          filename = code.co_filename
      61          funcname = code.co_name
      62          sourceline = linecache.getline(filename, lineno)
      63          sourceline = sourceline.strip()
      64          if funcname in ("?", "", None):
      65              item = "%s, line %d: %s" % (modname, lineno, sourceline)
      66          else:
      67              item = "%s.%s(...), line %d: %s" % (modname, funcname,
      68                                               lineno, sourceline)
      69          return item
      70  
      71      def GetSubList(self):
      72          frame, lineno = self.info
      73          sublist = []
      74          if frame.f_globals is not frame.f_locals:
      75              item = VariablesTreeItem("<locals>", frame.f_locals, self.flist)
      76              sublist.append(item)
      77          item = VariablesTreeItem("<globals>", frame.f_globals, self.flist)
      78          sublist.append(item)
      79          return sublist
      80  
      81      def OnDoubleClick(self):
      82          if self.flist:
      83              frame, lineno = self.info
      84              filename = frame.f_code.co_filename
      85              if os.path.isfile(filename):
      86                  self.flist.gotofileline(filename, lineno)
      87  
      88  
      89  class ESC[4;38;5;81mVariablesTreeItem(ESC[4;38;5;149mObjectTreeItem):
      90  
      91      def GetText(self):
      92          return self.labeltext
      93  
      94      def GetLabelText(self):
      95          return None
      96  
      97      def IsExpandable(self):
      98          return len(self.object) > 0
      99  
     100      def GetSubList(self):
     101          sublist = []
     102          for key in self.object.keys():
     103              try:
     104                  value = self.object[key]
     105              except KeyError:
     106                  continue
     107              def setfunction(value, key=key, object=self.object):
     108                  object[key] = value
     109              item = make_objecttreeitem(key + " =", value, setfunction)
     110              sublist.append(item)
     111          return sublist
     112  
     113  
     114  def _stack_viewer(parent):  # htest #
     115      from idlelib.pyshell import PyShellFileList
     116      top = tk.Toplevel(parent)
     117      top.title("Test StackViewer")
     118      x, y = map(int, parent.geometry().split('+')[1:])
     119      top.geometry("+%d+%d" % (x + 50, y + 175))
     120      flist = PyShellFileList(top)
     121      try: # to obtain a traceback object
     122          intentional_name_error
     123      except NameError as e:
     124          StackBrowser(top, e, flist=flist, top=top)
     125  
     126  
     127  if __name__ == '__main__':
     128      from unittest import main
     129      main('idlelib.idle_test.test_stackviewer', verbosity=2, exit=False)
     130  
     131      from idlelib.idle_test.htest import run
     132      run(_stack_viewer)