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