[Python-checkins] r87047 - in python/branches/py3k: Doc/library/pdb.rst Lib/pdb.py Misc/NEWS

georg.brandl python-checkins at python.org
Sat Dec 4 17:21:42 CET 2010


Author: georg.brandl
Date: Sat Dec  4 17:21:42 2010
New Revision: 87047

Log:
Add display/undisplay pdb commands.

Modified:
   python/branches/py3k/Doc/library/pdb.rst
   python/branches/py3k/Lib/pdb.py
   python/branches/py3k/Misc/NEWS

Modified: python/branches/py3k/Doc/library/pdb.rst
==============================================================================
--- python/branches/py3k/Doc/library/pdb.rst	(original)
+++ python/branches/py3k/Doc/library/pdb.rst	Sat Dec  4 17:21:42 2010
@@ -417,6 +417,22 @@
 
    .. versionadded:: 3.2
 
+.. pdbcommand:: display [expression]
+
+   Display the value of the expression if it changed, each time execution stops
+   in the current frame.
+
+   Without expression, list all display expressions for the current frame.
+
+   .. versionadded:: 3.2
+
+.. pdbcommand:: undisplay [expression]
+
+   Do not display the expression any more in the current frame.  Without
+   expression, clear all display expressions for the current frame.
+
+   .. versionadded:: 3.2
+
 .. pdbcommand:: interact
 
    Start an interative interpreter (using the :mod:`code` module) whose global

Modified: python/branches/py3k/Lib/pdb.py
==============================================================================
--- python/branches/py3k/Lib/pdb.py	(original)
+++ python/branches/py3k/Lib/pdb.py	Sat Dec  4 17:21:42 2010
@@ -125,6 +125,12 @@
     return 0
 
 
+class _rstr(str):
+    """String that doesn't quote its repr."""
+    def __repr__(self):
+        return self
+
+
 # Interaction prompt line will separate file and call info from code
 # text using value of line_prefix string.  A newline and arrow may
 # be to your liking.  You can set it once pdb is imported using the
@@ -142,6 +148,7 @@
             self.use_rawinput = 0
         self.prompt = '(Pdb) '
         self.aliases = {}
+        self.displaying = {}
         self.mainpyfile = ''
         self._wait_for_mainpyfile = False
         self.tb_lineno = {}
@@ -311,6 +318,20 @@
             except KeyboardInterrupt:
                 self.message('--KeyboardInterrupt--')
 
+    # Called before loop, handles display expressions
+    def preloop(self):
+        displaying = self.displaying.get(self.curframe)
+        if displaying:
+            for expr, oldvalue in displaying.items():
+                newvalue = self._getval_except(expr)
+                # check for identity first; this prevents custom __eq__ to
+                # be called at every loop, and also prevents instances whose
+                # fields are changed to be displayed
+                if newvalue is not oldvalue and newvalue != oldvalue:
+                    displaying[expr] = newvalue
+                    self.message('display %s: %r  [old: %r]' %
+                                 (expr, newvalue, oldvalue))
+
     def interaction(self, frame, traceback):
         if self.setup(frame, traceback):
             # no interaction desired at this time (happens if .pdbrc contains
@@ -1041,6 +1062,17 @@
             self.error(traceback.format_exception_only(*exc_info)[-1].strip())
             raise
 
+    def _getval_except(self, arg, frame=None):
+        try:
+            if frame is None:
+                return eval(arg, self.curframe.f_globals, self.curframe_locals)
+            else:
+                return eval(arg, frame.f_globals, frame.f_locals)
+        except:
+            exc_info = sys.exc_info()[:2]
+            err = traceback.format_exception_only(*exc_info)[-1].strip()
+            return _rstr('** raised %s **' % err)
+
     def do_p(self, arg):
         """p(rint) expression
         Print the value of the expression.
@@ -1195,6 +1227,38 @@
         # None of the above...
         self.message(type(value))
 
+    def do_display(self, arg):
+        """display [expression]
+
+        Display the value of the expression if it changed, each time execution
+        stops in the current frame.
+
+        Without expression, list all display expressions for the current frame.
+        """
+        if not arg:
+            self.message('Currently displaying:')
+            for item in self.displaying.get(self.curframe, {}).items():
+                self.message('%s: %r' % item)
+        else:
+            val = self._getval_except(arg)
+            self.displaying.setdefault(self.curframe, {})[arg] = val
+            self.message('display %s: %r' % (arg, val))
+
+    def do_undisplay(self, arg):
+        """undisplay [expression]
+
+        Do not display the expression any more in the current frame.
+
+        Without expression, clear all display expressions for the current frame.
+        """
+        if arg:
+            try:
+                del self.displaying.get(self.curframe, {})[arg]
+            except KeyError:
+                self.error('not displaying %s' % arg)
+        else:
+            self.displaying.pop(self.curframe, None)
+
     def do_interact(self, arg):
         """interact
 
@@ -1380,8 +1444,8 @@
         'help', 'where', 'down', 'up', 'break', 'tbreak', 'clear', 'disable',
         'enable', 'ignore', 'condition', 'commands', 'step', 'next', 'until',
         'jump', 'return', 'retval', 'run', 'continue', 'list', 'longlist',
-        'args', 'print', 'pp', 'whatis', 'source', 'interact', 'alias',
-        'unalias', 'debug', 'quit',
+        'args', 'print', 'pp', 'whatis', 'source', 'display', 'undisplay',
+        'interact', 'alias', 'unalias', 'debug', 'quit',
     ]
 
     for _command in _help_order:

Modified: python/branches/py3k/Misc/NEWS
==============================================================================
--- python/branches/py3k/Misc/NEWS	(original)
+++ python/branches/py3k/Misc/NEWS	Sat Dec  4 17:21:42 2010
@@ -49,6 +49,8 @@
 Library
 -------
 
+- Add the "display" and "undisplay" pdb commands.
+
 - Issue #7245: Add a SIGINT handler in pdb that allows to break a program
   again after a "continue" command.
 


More information about the Python-checkins mailing list