python (3.12.0)

(root)/
lib/
python3.12/
pdb.py
       1  #! /usr/bin/env python3
       2  
       3  """
       4  The Python Debugger Pdb
       5  =======================
       6  
       7  To use the debugger in its simplest form:
       8  
       9          >>> import pdb
      10          >>> pdb.run('<a statement>')
      11  
      12  The debugger's prompt is '(Pdb) '.  This will stop in the first
      13  function call in <a statement>.
      14  
      15  Alternatively, if a statement terminated with an unhandled exception,
      16  you can use pdb's post-mortem facility to inspect the contents of the
      17  traceback:
      18  
      19          >>> <a statement>
      20          <exception traceback>
      21          >>> import pdb
      22          >>> pdb.pm()
      23  
      24  The commands recognized by the debugger are listed in the next
      25  section.  Most can be abbreviated as indicated; e.g., h(elp) means
      26  that 'help' can be typed as 'h' or 'help' (but not as 'he' or 'hel',
      27  nor as 'H' or 'Help' or 'HELP').  Optional arguments are enclosed in
      28  square brackets.  Alternatives in the command syntax are separated
      29  by a vertical bar (|).
      30  
      31  A blank line repeats the previous command literally, except for
      32  'list', where it lists the next 11 lines.
      33  
      34  Commands that the debugger doesn't recognize are assumed to be Python
      35  statements and are executed in the context of the program being
      36  debugged.  Python statements can also be prefixed with an exclamation
      37  point ('!').  This is a powerful way to inspect the program being
      38  debugged; it is even possible to change variables or call functions.
      39  When an exception occurs in such a statement, the exception name is
      40  printed but the debugger's state is not changed.
      41  
      42  The debugger supports aliases, which can save typing.  And aliases can
      43  have parameters (see the alias help entry) which allows one a certain
      44  level of adaptability to the context under examination.
      45  
      46  Multiple commands may be entered on a single line, separated by the
      47  pair ';;'.  No intelligence is applied to separating the commands; the
      48  input is split at the first ';;', even if it is in the middle of a
      49  quoted string.
      50  
      51  If a file ".pdbrc" exists in your home directory or in the current
      52  directory, it is read in and executed as if it had been typed at the
      53  debugger prompt.  This is particularly useful for aliases.  If both
      54  files exist, the one in the home directory is read first and aliases
      55  defined there can be overridden by the local file.  This behavior can be
      56  disabled by passing the "readrc=False" argument to the Pdb constructor.
      57  
      58  Aside from aliases, the debugger is not directly programmable; but it
      59  is implemented as a class from which you can derive your own debugger
      60  class, which you can make as fancy as you like.
      61  
      62  
      63  Debugger commands
      64  =================
      65  
      66  """
      67  # NOTE: the actual command documentation is collected from docstrings of the
      68  # commands and is appended to __doc__ after the class has been defined.
      69  
      70  import os
      71  import io
      72  import re
      73  import sys
      74  import cmd
      75  import bdb
      76  import dis
      77  import code
      78  import glob
      79  import pprint
      80  import signal
      81  import inspect
      82  import tokenize
      83  import functools
      84  import traceback
      85  import linecache
      86  
      87  from typing import Union
      88  
      89  
      90  class ESC[4;38;5;81mRestart(ESC[4;38;5;149mException):
      91      """Causes a debugger to be restarted for the debugged python program."""
      92      pass
      93  
      94  __all__ = ["run", "pm", "Pdb", "runeval", "runctx", "runcall", "set_trace",
      95             "post_mortem", "help"]
      96  
      97  def find_function(funcname, filename):
      98      cre = re.compile(r'def\s+%s\s*[(]' % re.escape(funcname))
      99      try:
     100          fp = tokenize.open(filename)
     101      except OSError:
     102          return None
     103      # consumer of this info expects the first line to be 1
     104      with fp:
     105          for lineno, line in enumerate(fp, start=1):
     106              if cre.match(line):
     107                  return funcname, filename, lineno
     108      return None
     109  
     110  def lasti2lineno(code, lasti):
     111      linestarts = list(dis.findlinestarts(code))
     112      linestarts.reverse()
     113      for i, lineno in linestarts:
     114          if lasti >= i:
     115              return lineno
     116      return 0
     117  
     118  
     119  class ESC[4;38;5;81m_rstr(ESC[4;38;5;149mstr):
     120      """String that doesn't quote its repr."""
     121      def __repr__(self):
     122          return self
     123  
     124  
     125  class ESC[4;38;5;81m_ScriptTarget(ESC[4;38;5;149mstr):
     126      def __new__(cls, val):
     127          # Mutate self to be the "real path".
     128          res = super().__new__(cls, os.path.realpath(val))
     129  
     130          # Store the original path for error reporting.
     131          res.orig = val
     132  
     133          return res
     134  
     135      def check(self):
     136          if not os.path.exists(self):
     137              print('Error:', self.orig, 'does not exist')
     138              sys.exit(1)
     139  
     140          # Replace pdb's dir with script's dir in front of module search path.
     141          sys.path[0] = os.path.dirname(self)
     142  
     143      @property
     144      def filename(self):
     145          return self
     146  
     147      @property
     148      def namespace(self):
     149          return dict(
     150              __name__='__main__',
     151              __file__=self,
     152              __builtins__=__builtins__,
     153          )
     154  
     155      @property
     156      def code(self):
     157          with io.open_code(self) as fp:
     158              return f"exec(compile({fp.read()!r}, {self!r}, 'exec'))"
     159  
     160  
     161  class ESC[4;38;5;81m_ModuleTarget(ESC[4;38;5;149mstr):
     162      def check(self):
     163          try:
     164              self._details
     165          except Exception:
     166              traceback.print_exc()
     167              sys.exit(1)
     168  
     169      @functools.cached_property
     170      def _details(self):
     171          import runpy
     172          return runpy._get_module_details(self)
     173  
     174      @property
     175      def filename(self):
     176          return self.code.co_filename
     177  
     178      @property
     179      def code(self):
     180          name, spec, code = self._details
     181          return code
     182  
     183      @property
     184      def _spec(self):
     185          name, spec, code = self._details
     186          return spec
     187  
     188      @property
     189      def namespace(self):
     190          return dict(
     191              __name__='__main__',
     192              __file__=os.path.normcase(os.path.abspath(self.filename)),
     193              __package__=self._spec.parent,
     194              __loader__=self._spec.loader,
     195              __spec__=self._spec,
     196              __builtins__=__builtins__,
     197          )
     198  
     199  
     200  # Interaction prompt line will separate file and call info from code
     201  # text using value of line_prefix string.  A newline and arrow may
     202  # be to your liking.  You can set it once pdb is imported using the
     203  # command "pdb.line_prefix = '\n% '".
     204  # line_prefix = ': '    # Use this to get the old situation back
     205  line_prefix = '\n-> '   # Probably a better default
     206  
     207  class ESC[4;38;5;81mPdb(ESC[4;38;5;149mbdbESC[4;38;5;149m.ESC[4;38;5;149mBdb, ESC[4;38;5;149mcmdESC[4;38;5;149m.ESC[4;38;5;149mCmd):
     208  
     209      _previous_sigint_handler = None
     210  
     211      def __init__(self, completekey='tab', stdin=None, stdout=None, skip=None,
     212                   nosigint=False, readrc=True):
     213          bdb.Bdb.__init__(self, skip=skip)
     214          cmd.Cmd.__init__(self, completekey, stdin, stdout)
     215          sys.audit("pdb.Pdb")
     216          if stdout:
     217              self.use_rawinput = 0
     218          self.prompt = '(Pdb) '
     219          self.aliases = {}
     220          self.displaying = {}
     221          self.mainpyfile = ''
     222          self._wait_for_mainpyfile = False
     223          self.tb_lineno = {}
     224          # Try to load readline if it exists
     225          try:
     226              import readline
     227              # remove some common file name delimiters
     228              readline.set_completer_delims(' \t\n`@#$%^&*()=+[{]}\\|;:\'",<>?')
     229          except ImportError:
     230              pass
     231          self.allow_kbdint = False
     232          self.nosigint = nosigint
     233  
     234          # Read ~/.pdbrc and ./.pdbrc
     235          self.rcLines = []
     236          if readrc:
     237              try:
     238                  with open(os.path.expanduser('~/.pdbrc'), encoding='utf-8') as rcFile:
     239                      self.rcLines.extend(rcFile)
     240              except OSError:
     241                  pass
     242              try:
     243                  with open(".pdbrc", encoding='utf-8') as rcFile:
     244                      self.rcLines.extend(rcFile)
     245              except OSError:
     246                  pass
     247  
     248          self.commands = {} # associates a command list to breakpoint numbers
     249          self.commands_doprompt = {} # for each bp num, tells if the prompt
     250                                      # must be disp. after execing the cmd list
     251          self.commands_silent = {} # for each bp num, tells if the stack trace
     252                                    # must be disp. after execing the cmd list
     253          self.commands_defining = False # True while in the process of defining
     254                                         # a command list
     255          self.commands_bnum = None # The breakpoint number for which we are
     256                                    # defining a list
     257  
     258      def sigint_handler(self, signum, frame):
     259          if self.allow_kbdint:
     260              raise KeyboardInterrupt
     261          self.message("\nProgram interrupted. (Use 'cont' to resume).")
     262          self.set_step()
     263          self.set_trace(frame)
     264  
     265      def reset(self):
     266          bdb.Bdb.reset(self)
     267          self.forget()
     268  
     269      def forget(self):
     270          self.lineno = None
     271          self.stack = []
     272          self.curindex = 0
     273          if hasattr(self, 'curframe') and self.curframe:
     274              self.curframe.f_globals.pop('__pdb_convenience_variables', None)
     275          self.curframe = None
     276          self.tb_lineno.clear()
     277  
     278      def setup(self, f, tb):
     279          self.forget()
     280          self.stack, self.curindex = self.get_stack(f, tb)
     281          while tb:
     282              # when setting up post-mortem debugging with a traceback, save all
     283              # the original line numbers to be displayed along the current line
     284              # numbers (which can be different, e.g. due to finally clauses)
     285              lineno = lasti2lineno(tb.tb_frame.f_code, tb.tb_lasti)
     286              self.tb_lineno[tb.tb_frame] = lineno
     287              tb = tb.tb_next
     288          self.curframe = self.stack[self.curindex][0]
     289          # The f_locals dictionary is updated from the actual frame
     290          # locals whenever the .f_locals accessor is called, so we
     291          # cache it here to ensure that modifications are not overwritten.
     292          self.curframe_locals = self.curframe.f_locals
     293          self.set_convenience_variable(self.curframe, '_frame', self.curframe)
     294          return self.execRcLines()
     295  
     296      # Can be executed earlier than 'setup' if desired
     297      def execRcLines(self):
     298          if not self.rcLines:
     299              return
     300          # local copy because of recursion
     301          rcLines = self.rcLines
     302          rcLines.reverse()
     303          # execute every line only once
     304          self.rcLines = []
     305          while rcLines:
     306              line = rcLines.pop().strip()
     307              if line and line[0] != '#':
     308                  if self.onecmd(line):
     309                      # if onecmd returns True, the command wants to exit
     310                      # from the interaction, save leftover rc lines
     311                      # to execute before next interaction
     312                      self.rcLines += reversed(rcLines)
     313                      return True
     314  
     315      # Override Bdb methods
     316  
     317      def user_call(self, frame, argument_list):
     318          """This method is called when there is the remote possibility
     319          that we ever need to stop in this function."""
     320          if self._wait_for_mainpyfile:
     321              return
     322          if self.stop_here(frame):
     323              self.message('--Call--')
     324              self.interaction(frame, None)
     325  
     326      def user_line(self, frame):
     327          """This function is called when we stop or break at this line."""
     328          if self._wait_for_mainpyfile:
     329              if (self.mainpyfile != self.canonic(frame.f_code.co_filename)
     330                  or frame.f_lineno <= 0):
     331                  return
     332              self._wait_for_mainpyfile = False
     333          if self.bp_commands(frame):
     334              self.interaction(frame, None)
     335  
     336      def bp_commands(self, frame):
     337          """Call every command that was set for the current active breakpoint
     338          (if there is one).
     339  
     340          Returns True if the normal interaction function must be called,
     341          False otherwise."""
     342          # self.currentbp is set in bdb in Bdb.break_here if a breakpoint was hit
     343          if getattr(self, "currentbp", False) and \
     344                 self.currentbp in self.commands:
     345              currentbp = self.currentbp
     346              self.currentbp = 0
     347              lastcmd_back = self.lastcmd
     348              self.setup(frame, None)
     349              for line in self.commands[currentbp]:
     350                  self.onecmd(line)
     351              self.lastcmd = lastcmd_back
     352              if not self.commands_silent[currentbp]:
     353                  self.print_stack_entry(self.stack[self.curindex])
     354              if self.commands_doprompt[currentbp]:
     355                  self._cmdloop()
     356              self.forget()
     357              return
     358          return 1
     359  
     360      def user_return(self, frame, return_value):
     361          """This function is called when a return trap is set here."""
     362          if self._wait_for_mainpyfile:
     363              return
     364          frame.f_locals['__return__'] = return_value
     365          self.set_convenience_variable(frame, '_retval', return_value)
     366          self.message('--Return--')
     367          self.interaction(frame, None)
     368  
     369      def user_exception(self, frame, exc_info):
     370          """This function is called if an exception occurs,
     371          but only if we are to stop at or just below this level."""
     372          if self._wait_for_mainpyfile:
     373              return
     374          exc_type, exc_value, exc_traceback = exc_info
     375          frame.f_locals['__exception__'] = exc_type, exc_value
     376          self.set_convenience_variable(frame, '_exception', exc_value)
     377  
     378          # An 'Internal StopIteration' exception is an exception debug event
     379          # issued by the interpreter when handling a subgenerator run with
     380          # 'yield from' or a generator controlled by a for loop. No exception has
     381          # actually occurred in this case. The debugger uses this debug event to
     382          # stop when the debuggee is returning from such generators.
     383          prefix = 'Internal ' if (not exc_traceback
     384                                      and exc_type is StopIteration) else ''
     385          self.message('%s%s' % (prefix, self._format_exc(exc_value)))
     386          self.interaction(frame, exc_traceback)
     387  
     388      # General interaction function
     389      def _cmdloop(self):
     390          while True:
     391              try:
     392                  # keyboard interrupts allow for an easy way to cancel
     393                  # the current command, so allow them during interactive input
     394                  self.allow_kbdint = True
     395                  self.cmdloop()
     396                  self.allow_kbdint = False
     397                  break
     398              except KeyboardInterrupt:
     399                  self.message('--KeyboardInterrupt--')
     400  
     401      # Called before loop, handles display expressions
     402      # Set up convenience variable containers
     403      def preloop(self):
     404          displaying = self.displaying.get(self.curframe)
     405          if displaying:
     406              for expr, oldvalue in displaying.items():
     407                  newvalue = self._getval_except(expr)
     408                  # check for identity first; this prevents custom __eq__ to
     409                  # be called at every loop, and also prevents instances whose
     410                  # fields are changed to be displayed
     411                  if newvalue is not oldvalue and newvalue != oldvalue:
     412                      displaying[expr] = newvalue
     413                      self.message('display %s: %r  [old: %r]' %
     414                                   (expr, newvalue, oldvalue))
     415  
     416      def interaction(self, frame, traceback):
     417          # Restore the previous signal handler at the Pdb prompt.
     418          if Pdb._previous_sigint_handler:
     419              try:
     420                  signal.signal(signal.SIGINT, Pdb._previous_sigint_handler)
     421              except ValueError:  # ValueError: signal only works in main thread
     422                  pass
     423              else:
     424                  Pdb._previous_sigint_handler = None
     425          if self.setup(frame, traceback):
     426              # no interaction desired at this time (happens if .pdbrc contains
     427              # a command like "continue")
     428              self.forget()
     429              return
     430          self.print_stack_entry(self.stack[self.curindex])
     431          self._cmdloop()
     432          self.forget()
     433  
     434      def displayhook(self, obj):
     435          """Custom displayhook for the exec in default(), which prevents
     436          assignment of the _ variable in the builtins.
     437          """
     438          # reproduce the behavior of the standard displayhook, not printing None
     439          if obj is not None:
     440              self.message(repr(obj))
     441  
     442      def default(self, line):
     443          if line[:1] == '!': line = line[1:].strip()
     444          locals = self.curframe_locals
     445          globals = self.curframe.f_globals
     446          try:
     447              code = compile(line + '\n', '<stdin>', 'single')
     448              save_stdout = sys.stdout
     449              save_stdin = sys.stdin
     450              save_displayhook = sys.displayhook
     451              try:
     452                  sys.stdin = self.stdin
     453                  sys.stdout = self.stdout
     454                  sys.displayhook = self.displayhook
     455                  exec(code, globals, locals)
     456              finally:
     457                  sys.stdout = save_stdout
     458                  sys.stdin = save_stdin
     459                  sys.displayhook = save_displayhook
     460          except:
     461              self._error_exc()
     462  
     463      def precmd(self, line):
     464          """Handle alias expansion and ';;' separator."""
     465          if not line.strip():
     466              return line
     467          args = line.split()
     468          while args[0] in self.aliases:
     469              line = self.aliases[args[0]]
     470              ii = 1
     471              for tmpArg in args[1:]:
     472                  line = line.replace("%" + str(ii),
     473                                        tmpArg)
     474                  ii += 1
     475              line = line.replace("%*", ' '.join(args[1:]))
     476              args = line.split()
     477          # split into ';;' separated commands
     478          # unless it's an alias command
     479          if args[0] != 'alias':
     480              marker = line.find(';;')
     481              if marker >= 0:
     482                  # queue up everything after marker
     483                  next = line[marker+2:].lstrip()
     484                  self.cmdqueue.append(next)
     485                  line = line[:marker].rstrip()
     486  
     487          # Replace all the convenience variables
     488          line = re.sub(r'\$([a-zA-Z_][a-zA-Z0-9_]*)', r'__pdb_convenience_variables["\1"]', line)
     489          return line
     490  
     491      def onecmd(self, line):
     492          """Interpret the argument as though it had been typed in response
     493          to the prompt.
     494  
     495          Checks whether this line is typed at the normal prompt or in
     496          a breakpoint command list definition.
     497          """
     498          if not self.commands_defining:
     499              return cmd.Cmd.onecmd(self, line)
     500          else:
     501              return self.handle_command_def(line)
     502  
     503      def handle_command_def(self, line):
     504          """Handles one command line during command list definition."""
     505          cmd, arg, line = self.parseline(line)
     506          if not cmd:
     507              return
     508          if cmd == 'silent':
     509              self.commands_silent[self.commands_bnum] = True
     510              return # continue to handle other cmd def in the cmd list
     511          elif cmd == 'end':
     512              self.cmdqueue = []
     513              return 1 # end of cmd list
     514          cmdlist = self.commands[self.commands_bnum]
     515          if arg:
     516              cmdlist.append(cmd+' '+arg)
     517          else:
     518              cmdlist.append(cmd)
     519          # Determine if we must stop
     520          try:
     521              func = getattr(self, 'do_' + cmd)
     522          except AttributeError:
     523              func = self.default
     524          # one of the resuming commands
     525          if func.__name__ in self.commands_resuming:
     526              self.commands_doprompt[self.commands_bnum] = False
     527              self.cmdqueue = []
     528              return 1
     529          return
     530  
     531      # interface abstraction functions
     532  
     533      def message(self, msg):
     534          print(msg, file=self.stdout)
     535  
     536      def error(self, msg):
     537          print('***', msg, file=self.stdout)
     538  
     539      # convenience variables
     540  
     541      def set_convenience_variable(self, frame, name, value):
     542          if '__pdb_convenience_variables' not in frame.f_globals:
     543              frame.f_globals['__pdb_convenience_variables'] = {}
     544          frame.f_globals['__pdb_convenience_variables'][name] = value
     545  
     546      # Generic completion functions.  Individual complete_foo methods can be
     547      # assigned below to one of these functions.
     548  
     549      def _complete_location(self, text, line, begidx, endidx):
     550          # Complete a file/module/function location for break/tbreak/clear.
     551          if line.strip().endswith((':', ',')):
     552              # Here comes a line number or a condition which we can't complete.
     553              return []
     554          # First, try to find matching functions (i.e. expressions).
     555          try:
     556              ret = self._complete_expression(text, line, begidx, endidx)
     557          except Exception:
     558              ret = []
     559          # Then, try to complete file names as well.
     560          globs = glob.glob(glob.escape(text) + '*')
     561          for fn in globs:
     562              if os.path.isdir(fn):
     563                  ret.append(fn + '/')
     564              elif os.path.isfile(fn) and fn.lower().endswith(('.py', '.pyw')):
     565                  ret.append(fn + ':')
     566          return ret
     567  
     568      def _complete_bpnumber(self, text, line, begidx, endidx):
     569          # Complete a breakpoint number.  (This would be more helpful if we could
     570          # display additional info along with the completions, such as file/line
     571          # of the breakpoint.)
     572          return [str(i) for i, bp in enumerate(bdb.Breakpoint.bpbynumber)
     573                  if bp is not None and str(i).startswith(text)]
     574  
     575      def _complete_expression(self, text, line, begidx, endidx):
     576          # Complete an arbitrary expression.
     577          if not self.curframe:
     578              return []
     579          # Collect globals and locals.  It is usually not really sensible to also
     580          # complete builtins, and they clutter the namespace quite heavily, so we
     581          # leave them out.
     582          ns = {**self.curframe.f_globals, **self.curframe_locals}
     583          if '.' in text:
     584              # Walk an attribute chain up to the last part, similar to what
     585              # rlcompleter does.  This will bail if any of the parts are not
     586              # simple attribute access, which is what we want.
     587              dotted = text.split('.')
     588              try:
     589                  obj = ns[dotted[0]]
     590                  for part in dotted[1:-1]:
     591                      obj = getattr(obj, part)
     592              except (KeyError, AttributeError):
     593                  return []
     594              prefix = '.'.join(dotted[:-1]) + '.'
     595              return [prefix + n for n in dir(obj) if n.startswith(dotted[-1])]
     596          else:
     597              # Complete a simple name.
     598              return [n for n in ns.keys() if n.startswith(text)]
     599  
     600      # Command definitions, called by cmdloop()
     601      # The argument is the remaining string on the command line
     602      # Return true to exit from the command loop
     603  
     604      def do_commands(self, arg):
     605          """(Pdb) commands [bpnumber]
     606          (com) ...
     607          (com) end
     608          (Pdb)
     609  
     610          Specify a list of commands for breakpoint number bpnumber.
     611          The commands themselves are entered on the following lines.
     612          Type a line containing just 'end' to terminate the commands.
     613          The commands are executed when the breakpoint is hit.
     614  
     615          To remove all commands from a breakpoint, type commands and
     616          follow it immediately with end; that is, give no commands.
     617  
     618          With no bpnumber argument, commands refers to the last
     619          breakpoint set.
     620  
     621          You can use breakpoint commands to start your program up
     622          again.  Simply use the continue command, or step, or any other
     623          command that resumes execution.
     624  
     625          Specifying any command resuming execution (currently continue,
     626          step, next, return, jump, quit and their abbreviations)
     627          terminates the command list (as if that command was
     628          immediately followed by end).  This is because any time you
     629          resume execution (even with a simple next or step), you may
     630          encounter another breakpoint -- which could have its own
     631          command list, leading to ambiguities about which list to
     632          execute.
     633  
     634          If you use the 'silent' command in the command list, the usual
     635          message about stopping at a breakpoint is not printed.  This
     636          may be desirable for breakpoints that are to print a specific
     637          message and then continue.  If none of the other commands
     638          print anything, you will see no sign that the breakpoint was
     639          reached.
     640          """
     641          if not arg:
     642              bnum = len(bdb.Breakpoint.bpbynumber) - 1
     643          else:
     644              try:
     645                  bnum = int(arg)
     646              except:
     647                  self.error("Usage: commands [bnum]\n        ...\n        end")
     648                  return
     649          try:
     650              self.get_bpbynumber(bnum)
     651          except ValueError as err:
     652              self.error('cannot set commands: %s' % err)
     653              return
     654  
     655          self.commands_bnum = bnum
     656          # Save old definitions for the case of a keyboard interrupt.
     657          if bnum in self.commands:
     658              old_command_defs = (self.commands[bnum],
     659                                  self.commands_doprompt[bnum],
     660                                  self.commands_silent[bnum])
     661          else:
     662              old_command_defs = None
     663          self.commands[bnum] = []
     664          self.commands_doprompt[bnum] = True
     665          self.commands_silent[bnum] = False
     666  
     667          prompt_back = self.prompt
     668          self.prompt = '(com) '
     669          self.commands_defining = True
     670          try:
     671              self.cmdloop()
     672          except KeyboardInterrupt:
     673              # Restore old definitions.
     674              if old_command_defs:
     675                  self.commands[bnum] = old_command_defs[0]
     676                  self.commands_doprompt[bnum] = old_command_defs[1]
     677                  self.commands_silent[bnum] = old_command_defs[2]
     678              else:
     679                  del self.commands[bnum]
     680                  del self.commands_doprompt[bnum]
     681                  del self.commands_silent[bnum]
     682              self.error('command definition aborted, old commands restored')
     683          finally:
     684              self.commands_defining = False
     685              self.prompt = prompt_back
     686  
     687      complete_commands = _complete_bpnumber
     688  
     689      def do_break(self, arg, temporary = 0):
     690          """b(reak) [ ([filename:]lineno | function) [, condition] ]
     691  
     692          Without argument, list all breaks.
     693  
     694          With a line number argument, set a break at this line in the
     695          current file.  With a function name, set a break at the first
     696          executable line of that function.  If a second argument is
     697          present, it is a string specifying an expression which must
     698          evaluate to true before the breakpoint is honored.
     699  
     700          The line number may be prefixed with a filename and a colon,
     701          to specify a breakpoint in another file (probably one that
     702          hasn't been loaded yet).  The file is searched for on
     703          sys.path; the .py suffix may be omitted.
     704          """
     705          if not arg:
     706              if self.breaks:  # There's at least one
     707                  self.message("Num Type         Disp Enb   Where")
     708                  for bp in bdb.Breakpoint.bpbynumber:
     709                      if bp:
     710                          self.message(bp.bpformat())
     711              return
     712          # parse arguments; comma has lowest precedence
     713          # and cannot occur in filename
     714          filename = None
     715          lineno = None
     716          cond = None
     717          comma = arg.find(',')
     718          if comma > 0:
     719              # parse stuff after comma: "condition"
     720              cond = arg[comma+1:].lstrip()
     721              if err := self._compile_error_message(cond):
     722                  self.error('Invalid condition %s: %r' % (cond, err))
     723                  return
     724              arg = arg[:comma].rstrip()
     725          # parse stuff before comma: [filename:]lineno | function
     726          colon = arg.rfind(':')
     727          funcname = None
     728          if colon >= 0:
     729              filename = arg[:colon].rstrip()
     730              f = self.lookupmodule(filename)
     731              if not f:
     732                  self.error('%r not found from sys.path' % filename)
     733                  return
     734              else:
     735                  filename = f
     736              arg = arg[colon+1:].lstrip()
     737              try:
     738                  lineno = int(arg)
     739              except ValueError:
     740                  self.error('Bad lineno: %s' % arg)
     741                  return
     742          else:
     743              # no colon; can be lineno or function
     744              try:
     745                  lineno = int(arg)
     746              except ValueError:
     747                  try:
     748                      func = eval(arg,
     749                                  self.curframe.f_globals,
     750                                  self.curframe_locals)
     751                  except:
     752                      func = arg
     753                  try:
     754                      if hasattr(func, '__func__'):
     755                          func = func.__func__
     756                      code = func.__code__
     757                      #use co_name to identify the bkpt (function names
     758                      #could be aliased, but co_name is invariant)
     759                      funcname = code.co_name
     760                      lineno = code.co_firstlineno
     761                      filename = code.co_filename
     762                  except:
     763                      # last thing to try
     764                      (ok, filename, ln) = self.lineinfo(arg)
     765                      if not ok:
     766                          self.error('The specified object %r is not a function '
     767                                     'or was not found along sys.path.' % arg)
     768                          return
     769                      funcname = ok # ok contains a function name
     770                      lineno = int(ln)
     771          if not filename:
     772              filename = self.defaultFile()
     773          # Check for reasonable breakpoint
     774          line = self.checkline(filename, lineno)
     775          if line:
     776              # now set the break point
     777              err = self.set_break(filename, line, temporary, cond, funcname)
     778              if err:
     779                  self.error(err)
     780              else:
     781                  bp = self.get_breaks(filename, line)[-1]
     782                  self.message("Breakpoint %d at %s:%d" %
     783                               (bp.number, bp.file, bp.line))
     784  
     785      # To be overridden in derived debuggers
     786      def defaultFile(self):
     787          """Produce a reasonable default."""
     788          filename = self.curframe.f_code.co_filename
     789          if filename == '<string>' and self.mainpyfile:
     790              filename = self.mainpyfile
     791          return filename
     792  
     793      do_b = do_break
     794  
     795      complete_break = _complete_location
     796      complete_b = _complete_location
     797  
     798      def do_tbreak(self, arg):
     799          """tbreak [ ([filename:]lineno | function) [, condition] ]
     800  
     801          Same arguments as break, but sets a temporary breakpoint: it
     802          is automatically deleted when first hit.
     803          """
     804          self.do_break(arg, 1)
     805  
     806      complete_tbreak = _complete_location
     807  
     808      def lineinfo(self, identifier):
     809          failed = (None, None, None)
     810          # Input is identifier, may be in single quotes
     811          idstring = identifier.split("'")
     812          if len(idstring) == 1:
     813              # not in single quotes
     814              id = idstring[0].strip()
     815          elif len(idstring) == 3:
     816              # quoted
     817              id = idstring[1].strip()
     818          else:
     819              return failed
     820          if id == '': return failed
     821          parts = id.split('.')
     822          # Protection for derived debuggers
     823          if parts[0] == 'self':
     824              del parts[0]
     825              if len(parts) == 0:
     826                  return failed
     827          # Best first guess at file to look at
     828          fname = self.defaultFile()
     829          if len(parts) == 1:
     830              item = parts[0]
     831          else:
     832              # More than one part.
     833              # First is module, second is method/class
     834              f = self.lookupmodule(parts[0])
     835              if f:
     836                  fname = f
     837              item = parts[1]
     838          answer = find_function(item, fname)
     839          return answer or failed
     840  
     841      def checkline(self, filename, lineno):
     842          """Check whether specified line seems to be executable.
     843  
     844          Return `lineno` if it is, 0 if not (e.g. a docstring, comment, blank
     845          line or EOF). Warning: testing is not comprehensive.
     846          """
     847          # this method should be callable before starting debugging, so default
     848          # to "no globals" if there is no current frame
     849          frame = getattr(self, 'curframe', None)
     850          globs = frame.f_globals if frame else None
     851          line = linecache.getline(filename, lineno, globs)
     852          if not line:
     853              self.message('End of file')
     854              return 0
     855          line = line.strip()
     856          # Don't allow setting breakpoint at a blank line
     857          if (not line or (line[0] == '#') or
     858               (line[:3] == '"""') or line[:3] == "'''"):
     859              self.error('Blank or comment')
     860              return 0
     861          return lineno
     862  
     863      def do_enable(self, arg):
     864          """enable bpnumber [bpnumber ...]
     865  
     866          Enables the breakpoints given as a space separated list of
     867          breakpoint numbers.
     868          """
     869          args = arg.split()
     870          for i in args:
     871              try:
     872                  bp = self.get_bpbynumber(i)
     873              except ValueError as err:
     874                  self.error(err)
     875              else:
     876                  bp.enable()
     877                  self.message('Enabled %s' % bp)
     878  
     879      complete_enable = _complete_bpnumber
     880  
     881      def do_disable(self, arg):
     882          """disable bpnumber [bpnumber ...]
     883  
     884          Disables the breakpoints given as a space separated list of
     885          breakpoint numbers.  Disabling a breakpoint means it cannot
     886          cause the program to stop execution, but unlike clearing a
     887          breakpoint, it remains in the list of breakpoints and can be
     888          (re-)enabled.
     889          """
     890          args = arg.split()
     891          for i in args:
     892              try:
     893                  bp = self.get_bpbynumber(i)
     894              except ValueError as err:
     895                  self.error(err)
     896              else:
     897                  bp.disable()
     898                  self.message('Disabled %s' % bp)
     899  
     900      complete_disable = _complete_bpnumber
     901  
     902      def do_condition(self, arg):
     903          """condition bpnumber [condition]
     904  
     905          Set a new condition for the breakpoint, an expression which
     906          must evaluate to true before the breakpoint is honored.  If
     907          condition is absent, any existing condition is removed; i.e.,
     908          the breakpoint is made unconditional.
     909          """
     910          args = arg.split(' ', 1)
     911          try:
     912              cond = args[1]
     913              if err := self._compile_error_message(cond):
     914                  self.error('Invalid condition %s: %r' % (cond, err))
     915                  return
     916          except IndexError:
     917              cond = None
     918          try:
     919              bp = self.get_bpbynumber(args[0].strip())
     920          except IndexError:
     921              self.error('Breakpoint number expected')
     922          except ValueError as err:
     923              self.error(err)
     924          else:
     925              bp.cond = cond
     926              if not cond:
     927                  self.message('Breakpoint %d is now unconditional.' % bp.number)
     928              else:
     929                  self.message('New condition set for breakpoint %d.' % bp.number)
     930  
     931      complete_condition = _complete_bpnumber
     932  
     933      def do_ignore(self, arg):
     934          """ignore bpnumber [count]
     935  
     936          Set the ignore count for the given breakpoint number.  If
     937          count is omitted, the ignore count is set to 0.  A breakpoint
     938          becomes active when the ignore count is zero.  When non-zero,
     939          the count is decremented each time the breakpoint is reached
     940          and the breakpoint is not disabled and any associated
     941          condition evaluates to true.
     942          """
     943          args = arg.split()
     944          try:
     945              count = int(args[1].strip())
     946          except:
     947              count = 0
     948          try:
     949              bp = self.get_bpbynumber(args[0].strip())
     950          except IndexError:
     951              self.error('Breakpoint number expected')
     952          except ValueError as err:
     953              self.error(err)
     954          else:
     955              bp.ignore = count
     956              if count > 0:
     957                  if count > 1:
     958                      countstr = '%d crossings' % count
     959                  else:
     960                      countstr = '1 crossing'
     961                  self.message('Will ignore next %s of breakpoint %d.' %
     962                               (countstr, bp.number))
     963              else:
     964                  self.message('Will stop next time breakpoint %d is reached.'
     965                               % bp.number)
     966  
     967      complete_ignore = _complete_bpnumber
     968  
     969      def do_clear(self, arg):
     970          """cl(ear) [filename:lineno | bpnumber ...]
     971  
     972          With a space separated list of breakpoint numbers, clear
     973          those breakpoints.  Without argument, clear all breaks (but
     974          first ask confirmation).  With a filename:lineno argument,
     975          clear all breaks at that line in that file.
     976          """
     977          if not arg:
     978              try:
     979                  reply = input('Clear all breaks? ')
     980              except EOFError:
     981                  reply = 'no'
     982              reply = reply.strip().lower()
     983              if reply in ('y', 'yes'):
     984                  bplist = [bp for bp in bdb.Breakpoint.bpbynumber if bp]
     985                  self.clear_all_breaks()
     986                  for bp in bplist:
     987                      self.message('Deleted %s' % bp)
     988              return
     989          if ':' in arg:
     990              # Make sure it works for "clear C:\foo\bar.py:12"
     991              i = arg.rfind(':')
     992              filename = arg[:i]
     993              arg = arg[i+1:]
     994              try:
     995                  lineno = int(arg)
     996              except ValueError:
     997                  err = "Invalid line number (%s)" % arg
     998              else:
     999                  bplist = self.get_breaks(filename, lineno)[:]
    1000                  err = self.clear_break(filename, lineno)
    1001              if err:
    1002                  self.error(err)
    1003              else:
    1004                  for bp in bplist:
    1005                      self.message('Deleted %s' % bp)
    1006              return
    1007          numberlist = arg.split()
    1008          for i in numberlist:
    1009              try:
    1010                  bp = self.get_bpbynumber(i)
    1011              except ValueError as err:
    1012                  self.error(err)
    1013              else:
    1014                  self.clear_bpbynumber(i)
    1015                  self.message('Deleted %s' % bp)
    1016      do_cl = do_clear # 'c' is already an abbreviation for 'continue'
    1017  
    1018      complete_clear = _complete_location
    1019      complete_cl = _complete_location
    1020  
    1021      def do_where(self, arg):
    1022          """w(here)
    1023  
    1024          Print a stack trace, with the most recent frame at the bottom.
    1025          An arrow indicates the "current frame", which determines the
    1026          context of most commands.  'bt' is an alias for this command.
    1027          """
    1028          self.print_stack_trace()
    1029      do_w = do_where
    1030      do_bt = do_where
    1031  
    1032      def _select_frame(self, number):
    1033          assert 0 <= number < len(self.stack)
    1034          self.curindex = number
    1035          self.curframe = self.stack[self.curindex][0]
    1036          self.curframe_locals = self.curframe.f_locals
    1037          self.set_convenience_variable(self.curframe, '_frame', self.curframe)
    1038          self.print_stack_entry(self.stack[self.curindex])
    1039          self.lineno = None
    1040  
    1041      def do_up(self, arg):
    1042          """u(p) [count]
    1043  
    1044          Move the current frame count (default one) levels up in the
    1045          stack trace (to an older frame).
    1046          """
    1047          if self.curindex == 0:
    1048              self.error('Oldest frame')
    1049              return
    1050          try:
    1051              count = int(arg or 1)
    1052          except ValueError:
    1053              self.error('Invalid frame count (%s)' % arg)
    1054              return
    1055          if count < 0:
    1056              newframe = 0
    1057          else:
    1058              newframe = max(0, self.curindex - count)
    1059          self._select_frame(newframe)
    1060      do_u = do_up
    1061  
    1062      def do_down(self, arg):
    1063          """d(own) [count]
    1064  
    1065          Move the current frame count (default one) levels down in the
    1066          stack trace (to a newer frame).
    1067          """
    1068          if self.curindex + 1 == len(self.stack):
    1069              self.error('Newest frame')
    1070              return
    1071          try:
    1072              count = int(arg or 1)
    1073          except ValueError:
    1074              self.error('Invalid frame count (%s)' % arg)
    1075              return
    1076          if count < 0:
    1077              newframe = len(self.stack) - 1
    1078          else:
    1079              newframe = min(len(self.stack) - 1, self.curindex + count)
    1080          self._select_frame(newframe)
    1081      do_d = do_down
    1082  
    1083      def do_until(self, arg):
    1084          """unt(il) [lineno]
    1085  
    1086          Without argument, continue execution until the line with a
    1087          number greater than the current one is reached.  With a line
    1088          number, continue execution until a line with a number greater
    1089          or equal to that is reached.  In both cases, also stop when
    1090          the current frame returns.
    1091          """
    1092          if arg:
    1093              try:
    1094                  lineno = int(arg)
    1095              except ValueError:
    1096                  self.error('Error in argument: %r' % arg)
    1097                  return
    1098              if lineno <= self.curframe.f_lineno:
    1099                  self.error('"until" line number is smaller than current '
    1100                             'line number')
    1101                  return
    1102          else:
    1103              lineno = None
    1104          self.set_until(self.curframe, lineno)
    1105          return 1
    1106      do_unt = do_until
    1107  
    1108      def do_step(self, arg):
    1109          """s(tep)
    1110  
    1111          Execute the current line, stop at the first possible occasion
    1112          (either in a function that is called or in the current
    1113          function).
    1114          """
    1115          self.set_step()
    1116          return 1
    1117      do_s = do_step
    1118  
    1119      def do_next(self, arg):
    1120          """n(ext)
    1121  
    1122          Continue execution until the next line in the current function
    1123          is reached or it returns.
    1124          """
    1125          self.set_next(self.curframe)
    1126          return 1
    1127      do_n = do_next
    1128  
    1129      def do_run(self, arg):
    1130          """run [args...]
    1131  
    1132          Restart the debugged python program. If a string is supplied
    1133          it is split with "shlex", and the result is used as the new
    1134          sys.argv.  History, breakpoints, actions and debugger options
    1135          are preserved.  "restart" is an alias for "run".
    1136          """
    1137          if arg:
    1138              import shlex
    1139              argv0 = sys.argv[0:1]
    1140              try:
    1141                  sys.argv = shlex.split(arg)
    1142              except ValueError as e:
    1143                  self.error('Cannot run %s: %s' % (arg, e))
    1144                  return
    1145              sys.argv[:0] = argv0
    1146          # this is caught in the main debugger loop
    1147          raise Restart
    1148  
    1149      do_restart = do_run
    1150  
    1151      def do_return(self, arg):
    1152          """r(eturn)
    1153  
    1154          Continue execution until the current function returns.
    1155          """
    1156          self.set_return(self.curframe)
    1157          return 1
    1158      do_r = do_return
    1159  
    1160      def do_continue(self, arg):
    1161          """c(ont(inue))
    1162  
    1163          Continue execution, only stop when a breakpoint is encountered.
    1164          """
    1165          if not self.nosigint:
    1166              try:
    1167                  Pdb._previous_sigint_handler = \
    1168                      signal.signal(signal.SIGINT, self.sigint_handler)
    1169              except ValueError:
    1170                  # ValueError happens when do_continue() is invoked from
    1171                  # a non-main thread in which case we just continue without
    1172                  # SIGINT set. Would printing a message here (once) make
    1173                  # sense?
    1174                  pass
    1175          self.set_continue()
    1176          return 1
    1177      do_c = do_cont = do_continue
    1178  
    1179      def do_jump(self, arg):
    1180          """j(ump) lineno
    1181  
    1182          Set the next line that will be executed.  Only available in
    1183          the bottom-most frame.  This lets you jump back and execute
    1184          code again, or jump forward to skip code that you don't want
    1185          to run.
    1186  
    1187          It should be noted that not all jumps are allowed -- for
    1188          instance it is not possible to jump into the middle of a
    1189          for loop or out of a finally clause.
    1190          """
    1191          if self.curindex + 1 != len(self.stack):
    1192              self.error('You can only jump within the bottom frame')
    1193              return
    1194          try:
    1195              arg = int(arg)
    1196          except ValueError:
    1197              self.error("The 'jump' command requires a line number")
    1198          else:
    1199              try:
    1200                  # Do the jump, fix up our copy of the stack, and display the
    1201                  # new position
    1202                  self.curframe.f_lineno = arg
    1203                  self.stack[self.curindex] = self.stack[self.curindex][0], arg
    1204                  self.print_stack_entry(self.stack[self.curindex])
    1205              except ValueError as e:
    1206                  self.error('Jump failed: %s' % e)
    1207      do_j = do_jump
    1208  
    1209      def do_debug(self, arg):
    1210          """debug code
    1211  
    1212          Enter a recursive debugger that steps through the code
    1213          argument (which is an arbitrary expression or statement to be
    1214          executed in the current environment).
    1215          """
    1216          sys.settrace(None)
    1217          globals = self.curframe.f_globals
    1218          locals = self.curframe_locals
    1219          p = Pdb(self.completekey, self.stdin, self.stdout)
    1220          p.prompt = "(%s) " % self.prompt.strip()
    1221          self.message("ENTERING RECURSIVE DEBUGGER")
    1222          try:
    1223              sys.call_tracing(p.run, (arg, globals, locals))
    1224          except Exception:
    1225              self._error_exc()
    1226          self.message("LEAVING RECURSIVE DEBUGGER")
    1227          sys.settrace(self.trace_dispatch)
    1228          self.lastcmd = p.lastcmd
    1229  
    1230      complete_debug = _complete_expression
    1231  
    1232      def do_quit(self, arg):
    1233          """q(uit) | exit
    1234  
    1235          Quit from the debugger. The program being executed is aborted.
    1236          """
    1237          self._user_requested_quit = True
    1238          self.set_quit()
    1239          return 1
    1240  
    1241      do_q = do_quit
    1242      do_exit = do_quit
    1243  
    1244      def do_EOF(self, arg):
    1245          """EOF
    1246  
    1247          Handles the receipt of EOF as a command.
    1248          """
    1249          self.message('')
    1250          self._user_requested_quit = True
    1251          self.set_quit()
    1252          return 1
    1253  
    1254      def do_args(self, arg):
    1255          """a(rgs)
    1256  
    1257          Print the argument list of the current function.
    1258          """
    1259          co = self.curframe.f_code
    1260          dict = self.curframe_locals
    1261          n = co.co_argcount + co.co_kwonlyargcount
    1262          if co.co_flags & inspect.CO_VARARGS: n = n+1
    1263          if co.co_flags & inspect.CO_VARKEYWORDS: n = n+1
    1264          for i in range(n):
    1265              name = co.co_varnames[i]
    1266              if name in dict:
    1267                  self.message('%s = %r' % (name, dict[name]))
    1268              else:
    1269                  self.message('%s = *** undefined ***' % (name,))
    1270      do_a = do_args
    1271  
    1272      def do_retval(self, arg):
    1273          """retval
    1274  
    1275          Print the return value for the last return of a function.
    1276          """
    1277          if '__return__' in self.curframe_locals:
    1278              self.message(repr(self.curframe_locals['__return__']))
    1279          else:
    1280              self.error('Not yet returned!')
    1281      do_rv = do_retval
    1282  
    1283      def _getval(self, arg):
    1284          try:
    1285              return eval(arg, self.curframe.f_globals, self.curframe_locals)
    1286          except:
    1287              self._error_exc()
    1288              raise
    1289  
    1290      def _getval_except(self, arg, frame=None):
    1291          try:
    1292              if frame is None:
    1293                  return eval(arg, self.curframe.f_globals, self.curframe_locals)
    1294              else:
    1295                  return eval(arg, frame.f_globals, frame.f_locals)
    1296          except BaseException as exc:
    1297              return _rstr('** raised %s **' % self._format_exc(exc))
    1298  
    1299      def _error_exc(self):
    1300          exc = sys.exception()
    1301          self.error(self._format_exc(exc))
    1302  
    1303      def _msg_val_func(self, arg, func):
    1304          try:
    1305              val = self._getval(arg)
    1306          except:
    1307              return  # _getval() has displayed the error
    1308          try:
    1309              self.message(func(val))
    1310          except:
    1311              self._error_exc()
    1312  
    1313      def do_p(self, arg):
    1314          """p expression
    1315  
    1316          Print the value of the expression.
    1317          """
    1318          self._msg_val_func(arg, repr)
    1319  
    1320      def do_pp(self, arg):
    1321          """pp expression
    1322  
    1323          Pretty-print the value of the expression.
    1324          """
    1325          self._msg_val_func(arg, pprint.pformat)
    1326  
    1327      complete_print = _complete_expression
    1328      complete_p = _complete_expression
    1329      complete_pp = _complete_expression
    1330  
    1331      def do_list(self, arg):
    1332          """l(ist) [first[, last] | .]
    1333  
    1334          List source code for the current file.  Without arguments,
    1335          list 11 lines around the current line or continue the previous
    1336          listing.  With . as argument, list 11 lines around the current
    1337          line.  With one argument, list 11 lines starting at that line.
    1338          With two arguments, list the given range; if the second
    1339          argument is less than the first, it is a count.
    1340  
    1341          The current line in the current frame is indicated by "->".
    1342          If an exception is being debugged, the line where the
    1343          exception was originally raised or propagated is indicated by
    1344          ">>", if it differs from the current line.
    1345          """
    1346          self.lastcmd = 'list'
    1347          last = None
    1348          if arg and arg != '.':
    1349              try:
    1350                  if ',' in arg:
    1351                      first, last = arg.split(',')
    1352                      first = int(first.strip())
    1353                      last = int(last.strip())
    1354                      if last < first:
    1355                          # assume it's a count
    1356                          last = first + last
    1357                  else:
    1358                      first = int(arg.strip())
    1359                      first = max(1, first - 5)
    1360              except ValueError:
    1361                  self.error('Error in argument: %r' % arg)
    1362                  return
    1363          elif self.lineno is None or arg == '.':
    1364              first = max(1, self.curframe.f_lineno - 5)
    1365          else:
    1366              first = self.lineno + 1
    1367          if last is None:
    1368              last = first + 10
    1369          filename = self.curframe.f_code.co_filename
    1370          # gh-93696: stdlib frozen modules provide a useful __file__
    1371          # this workaround can be removed with the closure of gh-89815
    1372          if filename.startswith("<frozen"):
    1373              tmp = self.curframe.f_globals.get("__file__")
    1374              if isinstance(tmp, str):
    1375                  filename = tmp
    1376          breaklist = self.get_file_breaks(filename)
    1377          try:
    1378              lines = linecache.getlines(filename, self.curframe.f_globals)
    1379              self._print_lines(lines[first-1:last], first, breaklist,
    1380                                self.curframe)
    1381              self.lineno = min(last, len(lines))
    1382              if len(lines) < last:
    1383                  self.message('[EOF]')
    1384          except KeyboardInterrupt:
    1385              pass
    1386      do_l = do_list
    1387  
    1388      def do_longlist(self, arg):
    1389          """ll | longlist
    1390  
    1391          List the whole source code for the current function or frame.
    1392          """
    1393          filename = self.curframe.f_code.co_filename
    1394          breaklist = self.get_file_breaks(filename)
    1395          try:
    1396              lines, lineno = self._getsourcelines(self.curframe)
    1397          except OSError as err:
    1398              self.error(err)
    1399              return
    1400          self._print_lines(lines, lineno, breaklist, self.curframe)
    1401      do_ll = do_longlist
    1402  
    1403      def do_source(self, arg):
    1404          """source expression
    1405  
    1406          Try to get source code for the given object and display it.
    1407          """
    1408          try:
    1409              obj = self._getval(arg)
    1410          except:
    1411              return
    1412          try:
    1413              lines, lineno = self._getsourcelines(obj)
    1414          except (OSError, TypeError) as err:
    1415              self.error(err)
    1416              return
    1417          self._print_lines(lines, lineno)
    1418  
    1419      complete_source = _complete_expression
    1420  
    1421      def _print_lines(self, lines, start, breaks=(), frame=None):
    1422          """Print a range of lines."""
    1423          if frame:
    1424              current_lineno = frame.f_lineno
    1425              exc_lineno = self.tb_lineno.get(frame, -1)
    1426          else:
    1427              current_lineno = exc_lineno = -1
    1428          for lineno, line in enumerate(lines, start):
    1429              s = str(lineno).rjust(3)
    1430              if len(s) < 4:
    1431                  s += ' '
    1432              if lineno in breaks:
    1433                  s += 'B'
    1434              else:
    1435                  s += ' '
    1436              if lineno == current_lineno:
    1437                  s += '->'
    1438              elif lineno == exc_lineno:
    1439                  s += '>>'
    1440              self.message(s + '\t' + line.rstrip())
    1441  
    1442      def do_whatis(self, arg):
    1443          """whatis expression
    1444  
    1445          Print the type of the argument.
    1446          """
    1447          try:
    1448              value = self._getval(arg)
    1449          except:
    1450              # _getval() already printed the error
    1451              return
    1452          code = None
    1453          # Is it an instance method?
    1454          try:
    1455              code = value.__func__.__code__
    1456          except Exception:
    1457              pass
    1458          if code:
    1459              self.message('Method %s' % code.co_name)
    1460              return
    1461          # Is it a function?
    1462          try:
    1463              code = value.__code__
    1464          except Exception:
    1465              pass
    1466          if code:
    1467              self.message('Function %s' % code.co_name)
    1468              return
    1469          # Is it a class?
    1470          if value.__class__ is type:
    1471              self.message('Class %s.%s' % (value.__module__, value.__qualname__))
    1472              return
    1473          # None of the above...
    1474          self.message(type(value))
    1475  
    1476      complete_whatis = _complete_expression
    1477  
    1478      def do_display(self, arg):
    1479          """display [expression]
    1480  
    1481          Display the value of the expression if it changed, each time execution
    1482          stops in the current frame.
    1483  
    1484          Without expression, list all display expressions for the current frame.
    1485          """
    1486          if not arg:
    1487              if self.displaying:
    1488                  self.message('Currently displaying:')
    1489                  for item in self.displaying.get(self.curframe, {}).items():
    1490                      self.message('%s: %r' % item)
    1491              else:
    1492                  self.message('No expression is being displayed')
    1493          else:
    1494              if err := self._compile_error_message(arg):
    1495                  self.error('Unable to display %s: %r' % (arg, err))
    1496              else:
    1497                  val = self._getval_except(arg)
    1498                  self.displaying.setdefault(self.curframe, {})[arg] = val
    1499                  self.message('display %s: %r' % (arg, val))
    1500  
    1501      complete_display = _complete_expression
    1502  
    1503      def do_undisplay(self, arg):
    1504          """undisplay [expression]
    1505  
    1506          Do not display the expression any more in the current frame.
    1507  
    1508          Without expression, clear all display expressions for the current frame.
    1509          """
    1510          if arg:
    1511              try:
    1512                  del self.displaying.get(self.curframe, {})[arg]
    1513              except KeyError:
    1514                  self.error('not displaying %s' % arg)
    1515          else:
    1516              self.displaying.pop(self.curframe, None)
    1517  
    1518      def complete_undisplay(self, text, line, begidx, endidx):
    1519          return [e for e in self.displaying.get(self.curframe, {})
    1520                  if e.startswith(text)]
    1521  
    1522      def do_interact(self, arg):
    1523          """interact
    1524  
    1525          Start an interactive interpreter whose global namespace
    1526          contains all the (global and local) names found in the current scope.
    1527          """
    1528          ns = {**self.curframe.f_globals, **self.curframe_locals}
    1529          code.interact("*interactive*", local=ns)
    1530  
    1531      def do_alias(self, arg):
    1532          """alias [name [command]]
    1533  
    1534          Create an alias called 'name' that executes 'command'.  The
    1535          command must *not* be enclosed in quotes.  Replaceable
    1536          parameters can be indicated by %1, %2, and so on, while %* is
    1537          replaced by all the parameters.  If no command is given, the
    1538          current alias for name is shown. If no name is given, all
    1539          aliases are listed.
    1540  
    1541          Aliases may be nested and can contain anything that can be
    1542          legally typed at the pdb prompt.  Note!  You *can* override
    1543          internal pdb commands with aliases!  Those internal commands
    1544          are then hidden until the alias is removed.  Aliasing is
    1545          recursively applied to the first word of the command line; all
    1546          other words in the line are left alone.
    1547  
    1548          As an example, here are two useful aliases (especially when
    1549          placed in the .pdbrc file):
    1550  
    1551          # Print instance variables (usage "pi classInst")
    1552          alias pi for k in %1.__dict__.keys(): print("%1.",k,"=",%1.__dict__[k])
    1553          # Print instance variables in self
    1554          alias ps pi self
    1555          """
    1556          args = arg.split()
    1557          if len(args) == 0:
    1558              keys = sorted(self.aliases.keys())
    1559              for alias in keys:
    1560                  self.message("%s = %s" % (alias, self.aliases[alias]))
    1561              return
    1562          if args[0] in self.aliases and len(args) == 1:
    1563              self.message("%s = %s" % (args[0], self.aliases[args[0]]))
    1564          else:
    1565              self.aliases[args[0]] = ' '.join(args[1:])
    1566  
    1567      def do_unalias(self, arg):
    1568          """unalias name
    1569  
    1570          Delete the specified alias.
    1571          """
    1572          args = arg.split()
    1573          if len(args) == 0: return
    1574          if args[0] in self.aliases:
    1575              del self.aliases[args[0]]
    1576  
    1577      def complete_unalias(self, text, line, begidx, endidx):
    1578          return [a for a in self.aliases if a.startswith(text)]
    1579  
    1580      # List of all the commands making the program resume execution.
    1581      commands_resuming = ['do_continue', 'do_step', 'do_next', 'do_return',
    1582                           'do_quit', 'do_jump']
    1583  
    1584      # Print a traceback starting at the top stack frame.
    1585      # The most recently entered frame is printed last;
    1586      # this is different from dbx and gdb, but consistent with
    1587      # the Python interpreter's stack trace.
    1588      # It is also consistent with the up/down commands (which are
    1589      # compatible with dbx and gdb: up moves towards 'main()'
    1590      # and down moves towards the most recent stack frame).
    1591  
    1592      def print_stack_trace(self):
    1593          try:
    1594              for frame_lineno in self.stack:
    1595                  self.print_stack_entry(frame_lineno)
    1596          except KeyboardInterrupt:
    1597              pass
    1598  
    1599      def print_stack_entry(self, frame_lineno, prompt_prefix=line_prefix):
    1600          frame, lineno = frame_lineno
    1601          if frame is self.curframe:
    1602              prefix = '> '
    1603          else:
    1604              prefix = '  '
    1605          self.message(prefix +
    1606                       self.format_stack_entry(frame_lineno, prompt_prefix))
    1607  
    1608      # Provide help
    1609  
    1610      def do_help(self, arg):
    1611          """h(elp)
    1612  
    1613          Without argument, print the list of available commands.
    1614          With a command name as argument, print help about that command.
    1615          "help pdb" shows the full pdb documentation.
    1616          "help exec" gives help on the ! command.
    1617          """
    1618          if not arg:
    1619              return cmd.Cmd.do_help(self, arg)
    1620          try:
    1621              try:
    1622                  topic = getattr(self, 'help_' + arg)
    1623                  return topic()
    1624              except AttributeError:
    1625                  command = getattr(self, 'do_' + arg)
    1626          except AttributeError:
    1627              self.error('No help for %r' % arg)
    1628          else:
    1629              if sys.flags.optimize >= 2:
    1630                  self.error('No help for %r; please do not run Python with -OO '
    1631                             'if you need command help' % arg)
    1632                  return
    1633              if command.__doc__ is None:
    1634                  self.error('No help for %r; __doc__ string missing' % arg)
    1635                  return
    1636              self.message(self._help_message_from_doc(command.__doc__))
    1637  
    1638      do_h = do_help
    1639  
    1640      def help_exec(self):
    1641          """(!) statement
    1642  
    1643          Execute the (one-line) statement in the context of the current
    1644          stack frame.  The exclamation point can be omitted unless the
    1645          first word of the statement resembles a debugger command, e.g.:
    1646          (Pdb) ! n=42
    1647          (Pdb)
    1648  
    1649          To assign to a global variable you must always prefix the command with
    1650          a 'global' command, e.g.:
    1651          (Pdb) global list_options; list_options = ['-l']
    1652          (Pdb)
    1653          """
    1654          self.message((self.help_exec.__doc__ or '').strip())
    1655  
    1656      def help_pdb(self):
    1657          help()
    1658  
    1659      # other helper functions
    1660  
    1661      def lookupmodule(self, filename):
    1662          """Helper function for break/clear parsing -- may be overridden.
    1663  
    1664          lookupmodule() translates (possibly incomplete) file or module name
    1665          into an absolute file name.
    1666          """
    1667          if os.path.isabs(filename) and  os.path.exists(filename):
    1668              return filename
    1669          f = os.path.join(sys.path[0], filename)
    1670          if  os.path.exists(f) and self.canonic(f) == self.mainpyfile:
    1671              return f
    1672          root, ext = os.path.splitext(filename)
    1673          if ext == '':
    1674              filename = filename + '.py'
    1675          if os.path.isabs(filename):
    1676              return filename
    1677          for dirname in sys.path:
    1678              while os.path.islink(dirname):
    1679                  dirname = os.readlink(dirname)
    1680              fullname = os.path.join(dirname, filename)
    1681              if os.path.exists(fullname):
    1682                  return fullname
    1683          return None
    1684  
    1685      def _run(self, target: Union[_ModuleTarget, _ScriptTarget]):
    1686          # When bdb sets tracing, a number of call and line events happen
    1687          # BEFORE debugger even reaches user's code (and the exact sequence of
    1688          # events depends on python version). Take special measures to
    1689          # avoid stopping before reaching the main script (see user_line and
    1690          # user_call for details).
    1691          self._wait_for_mainpyfile = True
    1692          self._user_requested_quit = False
    1693  
    1694          self.mainpyfile = self.canonic(target.filename)
    1695  
    1696          # The target has to run in __main__ namespace (or imports from
    1697          # __main__ will break). Clear __main__ and replace with
    1698          # the target namespace.
    1699          import __main__
    1700          __main__.__dict__.clear()
    1701          __main__.__dict__.update(target.namespace)
    1702  
    1703          self.run(target.code)
    1704  
    1705      def _format_exc(self, exc: BaseException):
    1706          return traceback.format_exception_only(exc)[-1].strip()
    1707  
    1708      def _compile_error_message(self, expr):
    1709          """Return the error message as string if compiling `expr` fails."""
    1710          try:
    1711              compile(expr, "<stdin>", "eval")
    1712          except SyntaxError as exc:
    1713              return _rstr(self._format_exc(exc))
    1714          return ""
    1715  
    1716      def _getsourcelines(self, obj):
    1717          # GH-103319
    1718          # inspect.getsourcelines() returns lineno = 0 for
    1719          # module-level frame which breaks our code print line number
    1720          # This method should be replaced by inspect.getsourcelines(obj)
    1721          # once this bug is fixed in inspect
    1722          lines, lineno = inspect.getsourcelines(obj)
    1723          lineno = max(1, lineno)
    1724          return lines, lineno
    1725  
    1726      def _help_message_from_doc(self, doc):
    1727          lines = [line.strip() for line in doc.rstrip().splitlines()]
    1728          if not lines:
    1729              return "No help message found."
    1730          if "" in lines:
    1731              usage_end = lines.index("")
    1732          else:
    1733              usage_end = 1
    1734          formatted = []
    1735          indent = " " * len(self.prompt)
    1736          for i, line in enumerate(lines):
    1737              if i == 0:
    1738                  prefix = "Usage: "
    1739              elif i < usage_end:
    1740                  prefix = "       "
    1741              else:
    1742                  prefix = ""
    1743              formatted.append(indent + prefix + line)
    1744          return "\n".join(formatted)
    1745  
    1746  # Collect all command help into docstring, if not run with -OO
    1747  
    1748  if __doc__ is not None:
    1749      # unfortunately we can't guess this order from the class definition
    1750      _help_order = [
    1751          'help', 'where', 'down', 'up', 'break', 'tbreak', 'clear', 'disable',
    1752          'enable', 'ignore', 'condition', 'commands', 'step', 'next', 'until',
    1753          'jump', 'return', 'retval', 'run', 'continue', 'list', 'longlist',
    1754          'args', 'p', 'pp', 'whatis', 'source', 'display', 'undisplay',
    1755          'interact', 'alias', 'unalias', 'debug', 'quit',
    1756      ]
    1757  
    1758      for _command in _help_order:
    1759          __doc__ += getattr(Pdb, 'do_' + _command).__doc__.strip() + '\n\n'
    1760      __doc__ += Pdb.help_exec.__doc__
    1761  
    1762      del _help_order, _command
    1763  
    1764  
    1765  # Simplified interface
    1766  
    1767  def run(statement, globals=None, locals=None):
    1768      """Execute the *statement* (given as a string or a code object)
    1769      under debugger control.
    1770  
    1771      The debugger prompt appears before any code is executed; you can set
    1772      breakpoints and type continue, or you can step through the statement
    1773      using step or next.
    1774  
    1775      The optional *globals* and *locals* arguments specify the
    1776      environment in which the code is executed; by default the
    1777      dictionary of the module __main__ is used (see the explanation of
    1778      the built-in exec() or eval() functions.).
    1779      """
    1780      Pdb().run(statement, globals, locals)
    1781  
    1782  def runeval(expression, globals=None, locals=None):
    1783      """Evaluate the *expression* (given as a string or a code object)
    1784      under debugger control.
    1785  
    1786      When runeval() returns, it returns the value of the expression.
    1787      Otherwise this function is similar to run().
    1788      """
    1789      return Pdb().runeval(expression, globals, locals)
    1790  
    1791  def runctx(statement, globals, locals):
    1792      # B/W compatibility
    1793      run(statement, globals, locals)
    1794  
    1795  def runcall(*args, **kwds):
    1796      """Call the function (a function or method object, not a string)
    1797      with the given arguments.
    1798  
    1799      When runcall() returns, it returns whatever the function call
    1800      returned. The debugger prompt appears as soon as the function is
    1801      entered.
    1802      """
    1803      return Pdb().runcall(*args, **kwds)
    1804  
    1805  def set_trace(*, header=None):
    1806      """Enter the debugger at the calling stack frame.
    1807  
    1808      This is useful to hard-code a breakpoint at a given point in a
    1809      program, even if the code is not otherwise being debugged (e.g. when
    1810      an assertion fails). If given, *header* is printed to the console
    1811      just before debugging begins.
    1812      """
    1813      pdb = Pdb()
    1814      if header is not None:
    1815          pdb.message(header)
    1816      pdb.set_trace(sys._getframe().f_back)
    1817  
    1818  # Post-Mortem interface
    1819  
    1820  def post_mortem(t=None):
    1821      """Enter post-mortem debugging of the given *traceback* object.
    1822  
    1823      If no traceback is given, it uses the one of the exception that is
    1824      currently being handled (an exception must be being handled if the
    1825      default is to be used).
    1826      """
    1827      # handling the default
    1828      if t is None:
    1829          exc = sys.exception()
    1830          if exc is not None:
    1831              t = exc.__traceback__
    1832  
    1833      if t is None:
    1834          raise ValueError("A valid traceback must be passed if no "
    1835                           "exception is being handled")
    1836  
    1837      p = Pdb()
    1838      p.reset()
    1839      p.interaction(None, t)
    1840  
    1841  def pm():
    1842      """Enter post-mortem debugging of the traceback found in sys.last_traceback."""
    1843      if hasattr(sys, 'last_exc'):
    1844          tb = sys.last_exc.__traceback__
    1845      else:
    1846          tb = sys.last_traceback
    1847      post_mortem(tb)
    1848  
    1849  
    1850  # Main program for testing
    1851  
    1852  TESTCMD = 'import x; x.main()'
    1853  
    1854  def test():
    1855      run(TESTCMD)
    1856  
    1857  # print help
    1858  def help():
    1859      import pydoc
    1860      pydoc.pager(__doc__)
    1861  
    1862  _usage = """\
    1863  usage: pdb.py [-c command] ... [-m module | pyfile] [arg] ...
    1864  
    1865  Debug the Python program given by pyfile. Alternatively,
    1866  an executable module or package to debug can be specified using
    1867  the -m switch.
    1868  
    1869  Initial commands are read from .pdbrc files in your home directory
    1870  and in the current directory, if they exist.  Commands supplied with
    1871  -c are executed after commands from .pdbrc files.
    1872  
    1873  To let the script run until an exception occurs, use "-c continue".
    1874  To let the script run up to a given line X in the debugged file, use
    1875  "-c 'until X'"."""
    1876  
    1877  
    1878  def main():
    1879      import getopt
    1880  
    1881      opts, args = getopt.getopt(sys.argv[1:], 'mhc:', ['help', 'command='])
    1882  
    1883      if not args:
    1884          print(_usage)
    1885          sys.exit(2)
    1886  
    1887      if any(opt in ['-h', '--help'] for opt, optarg in opts):
    1888          print(_usage)
    1889          sys.exit()
    1890  
    1891      commands = [optarg for opt, optarg in opts if opt in ['-c', '--command']]
    1892  
    1893      module_indicated = any(opt in ['-m'] for opt, optarg in opts)
    1894      cls = _ModuleTarget if module_indicated else _ScriptTarget
    1895      target = cls(args[0])
    1896  
    1897      target.check()
    1898  
    1899      sys.argv[:] = args      # Hide "pdb.py" and pdb options from argument list
    1900  
    1901      # Note on saving/restoring sys.argv: it's a good idea when sys.argv was
    1902      # modified by the script being debugged. It's a bad idea when it was
    1903      # changed by the user from the command line. There is a "restart" command
    1904      # which allows explicit specification of command line arguments.
    1905      pdb = Pdb()
    1906      pdb.rcLines.extend(commands)
    1907      while True:
    1908          try:
    1909              pdb._run(target)
    1910              if pdb._user_requested_quit:
    1911                  break
    1912              print("The program finished and will be restarted")
    1913          except Restart:
    1914              print("Restarting", target, "with arguments:")
    1915              print("\t" + " ".join(sys.argv[1:]))
    1916          except SystemExit as e:
    1917              # In most cases SystemExit does not warrant a post-mortem session.
    1918              print("The program exited via sys.exit(). Exit status:", end=' ')
    1919              print(e)
    1920          except SyntaxError:
    1921              traceback.print_exc()
    1922              sys.exit(1)
    1923          except BaseException as e:
    1924              traceback.print_exc()
    1925              print("Uncaught exception. Entering post mortem debugging")
    1926              print("Running 'cont' or 'step' will restart the program")
    1927              t = e.__traceback__
    1928              pdb.interaction(None, t)
    1929              print("Post mortem debugger finished. The " + target +
    1930                    " will be restarted")
    1931  
    1932  
    1933  # When invoked as main program, invoke the debugger on a script
    1934  if __name__ == '__main__':
    1935      import pdb
    1936      pdb.main()