diff --git a/IPython/Debugger.py b/IPython/Debugger.py index 1afdc4e..ab4ec5a 100644 --- a/IPython/Debugger.py +++ b/IPython/Debugger.py @@ -15,7 +15,7 @@ details on the PSF (Python Software Foundation) standard license, see: http://www.python.org/2.2.3/license.html -$Id: Debugger.py 1787 2006-09-27 06:56:29Z fperez $""" +$Id: Debugger.py 1853 2006-10-30 17:00:39Z vivainio $""" #***************************************************************************** # @@ -40,13 +40,41 @@ import bdb import cmd import linecache import os -import pdb import sys from IPython import PyColorize, ColorANSI from IPython.genutils import Term from IPython.excolors import ExceptionColors +# See if we can use pydb. +has_pydb = False +prompt = 'ipdb>' +if sys.version[:3] >= '2.5': + try: + import pydb + if hasattr(pydb.pydb, "runl"): + has_pydb = True + from pydb import Pdb as OldPdb + prompt = 'ipydb>' + except ImportError: + pass + +if has_pydb: + from pydb import Pdb as OldPdb +else: + from pdb import Pdb as OldPdb + +def decorate_fn_with_doc(new_fn, old_fn, additional_text=""): + """Make new_fn have old_fn's doc string. This is particularly useful + for the do_... commands that hook into the help system. + Adapted from from a comp.lang.python posting + by Duncan Booth.""" + def wrapper(*args, **kw): + return new_fn(*args, **kw) + if old_fn.__doc__: + wrapper.__doc__ = old_fn.__doc__ + additional_text + return wrapper + def _file_lines(fname): """Return the contents of a named file as a list of lines. @@ -62,7 +90,7 @@ def _file_lines(fname): outfile.close() return out -class Pdb(pdb.Pdb): +class Pdb(OldPdb): """Modified Pdb class, does not load readline.""" if sys.version[:3] >= '2.5': @@ -70,10 +98,33 @@ class Pdb(pdb.Pdb): stdin=None, stdout=None): # Parent constructor: - pdb.Pdb.__init__(self,completekey,stdin,stdout) + OldPdb.__init__(self,completekey,stdin,stdout) # IPython changes... - self.prompt = 'ipdb> ' # The default prompt is '(Pdb)' + self.prompt = prompt # The default prompt is '(Pdb)' + self.is_pydb = prompt == 'ipydb>' + + if self.is_pydb: + + # iplib.py's ipalias seems to want pdb's checkline + # which located in pydb.fn + import pydb.fns + self.checkline = lambda filename, lineno: \ + pydb.fns.checkline(self, filename, lineno) + + self.curframe = None + self.do_restart = self.new_do_restart + + self.old_all_completions = __IPYTHON__.Completer.all_completions + __IPYTHON__.Completer.all_completions=self.all_completions + + # Do we have access to pydb's list command parser? + self.do_list = decorate_fn_with_doc(self.list_command_pydb, + OldPdb.do_list) + self.do_l = self.do_list + self.do_frame = decorate_fn_with_doc(self.new_do_frame, + OldPdb.do_frame) + self.aliases = {} # Create color table: we copy the default one from the traceback @@ -143,17 +194,34 @@ class Pdb(pdb.Pdb): def interaction(self, frame, traceback): __IPYTHON__.set_completer_frame(frame) - pdb.Pdb.interaction(self, frame, traceback) + OldPdb.interaction(self, frame, traceback) + + def new_do_up(self, arg): + OldPdb.do_up(self, arg) + __IPYTHON__.set_completer_frame(self.curframe) + do_u = do_up = decorate_fn_with_doc(new_do_up, OldPdb.do_up) - def do_up(self, arg): - pdb.Pdb.do_up(self, arg) + def new_do_down(self, arg): + OldPdb.do_down(self, arg) __IPYTHON__.set_completer_frame(self.curframe) - do_u = do_up - def do_down(self, arg): - pdb.Pdb.do_down(self, arg) + do_d = do_down = decorate_fn_with_doc(new_do_down, OldPdb.do_down) + + def new_do_frame(self, arg): + OldPdb.do_frame(self, arg) __IPYTHON__.set_completer_frame(self.curframe) - do_d = do_down + + def new_do_quit(self, arg): + __IPYTHON__.Completer.all_completions=self.old_all_completions + return OldPdb.do_quit(self, arg) + + do_q = do_quit = decorate_fn_with_doc(new_do_quit, OldPdb.do_quit) + + def new_do_restart(self, arg): + """Restart command. In the context of ipython this is exactly the same + thing as 'quit'.""" + self.msg("Restart doesn't make sense here. Using 'quit' instead.") + return self.do_quit(arg) def postloop(self): __IPYTHON__.set_completer_frame(None) @@ -263,6 +331,39 @@ class Pdb(pdb.Pdb): return line + def list_command_pydb(self, arg): + """List command to use if we have a newer pydb installed""" + filename, first, last = OldPdb.parse_list_cmd(self, arg) + if filename is not None: + self.print_list_lines(filename, first, last) + + def print_list_lines(self, filename, first, last): + """The printing (as opposed to the parsing part of a 'list' + command.""" + try: + Colors = self.color_scheme_table.active_colors + ColorsNormal = Colors.Normal + tpl_line = '%%s%s%%s %s%%s' % (Colors.lineno, ColorsNormal) + tpl_line_em = '%%s%s%%s %s%%s%s' % (Colors.linenoEm, Colors.line, ColorsNormal) + src = [] + for lineno in range(first, last+1): + line = linecache.getline(filename, lineno) + if not line: + break + + if lineno == self.curframe.f_lineno: + line = self.__format_line(tpl_line_em, filename, lineno, line, arrow = True) + else: + line = self.__format_line(tpl_line, filename, lineno, line, arrow = False) + + src.append(line) + self.lineno = lineno + + print >>Term.cout, ''.join(src) + + except KeyboardInterrupt: + pass + def do_list(self, arg): self.lastcmd = 'list' last = None @@ -287,29 +388,24 @@ class Pdb(pdb.Pdb): first = self.lineno + 1 if last is None: last = first + 10 - filename = self.curframe.f_code.co_filename - try: - Colors = self.color_scheme_table.active_colors - ColorsNormal = Colors.Normal - tpl_line = '%%s%s%%s %s%%s' % (Colors.lineno, ColorsNormal) - tpl_line_em = '%%s%s%%s %s%%s%s' % (Colors.linenoEm, Colors.line, ColorsNormal) - src = [] - for lineno in range(first, last+1): - line = linecache.getline(filename, lineno) - if not line: - break - - if lineno == self.curframe.f_lineno: - line = self.__format_line(tpl_line_em, filename, lineno, line, arrow = True) - else: - line = self.__format_line(tpl_line, filename, lineno, line, arrow = False) - - src.append(line) - self.lineno = lineno - - print >>Term.cout, ''.join(src) - - except KeyboardInterrupt: - pass + self.print_list_lines(self.curframe.f_code.co_filename, first, last) do_l = do_list + + def do_pdef(self, arg): + """The debugger interface to magic_pdef""" + namespaces = [('Locals', self.curframe.f_locals), + ('Globals', self.curframe.f_globals)] + __IPYTHON__.magic_pdef(arg, namespaces=namespaces) + + def do_pdoc(self, arg): + """The debugger interface to magic_pdoc""" + namespaces = [('Locals', self.curframe.f_locals), + ('Globals', self.curframe.f_globals)] + __IPYTHON__.magic_pdoc(arg, namespaces=namespaces) + + def do_pinfo(self, arg): + """The debugger equivalant of ?obj""" + namespaces = [('Locals', self.curframe.f_locals), + ('Globals', self.curframe.f_globals)] + __IPYTHON__.magic_pinfo("pinfo %s" % arg, namespaces=namespaces) diff --git a/IPython/iplib.py b/IPython/iplib.py index 7dc13df..1265422 100644 --- a/IPython/iplib.py +++ b/IPython/iplib.py @@ -6,7 +6,7 @@ Requires Python 2.3 or newer. This file contains all the classes and helper functions specific to IPython. -$Id: iplib.py 1850 2006-10-28 19:48:13Z fptest $ +$Id: iplib.py 1853 2006-10-30 17:00:39Z vivainio $ """ #***************************************************************************** @@ -47,7 +47,6 @@ import inspect import keyword import new import os -import pdb import pydoc import re import shutil @@ -1361,11 +1360,20 @@ want to merge them back into the new files.""" % locals() self.SyntaxTB(etype,value,[]) def debugger(self): - """Call the pdb debugger.""" + """Call the pydb/pdb debugger.""" if not self.rc.pdb: return - pdb.pm() + have_pydb = False + if sys.version[:3] >= '2.5': + try: + from pydb import pm + have_pydb = True + except ImportError: + pass + if not have_pydb: + from pdb import pm + pm() def showtraceback(self,exc_tuple = None,filename=None,tb_offset=None): """Display the exception that just occurred. diff --git a/doc/ChangeLog b/doc/ChangeLog index 9222adf..6b531cf 100644 --- a/doc/ChangeLog +++ b/doc/ChangeLog @@ -1,3 +1,9 @@ +2006-10-30 Ville Vainio + + * Debugger.py, iplib.py (debugger()): Add last set of Rocky + Bernsteins's patches for pydb integration. + http://bashdb.sourceforge.net/pydb/ + 2006-10-28 Fernando Perez * IPython/UserConfig/ipythonrc-scipy: minor clenaups to remove old @@ -22,7 +28,7 @@ file around %run commands to prevent side effects from %runned programs that might use readline (e.g. pydb). - * extensions/pydb_ipy.py: Adds %pydb magic when imported, for + * extensions/ipy_pydb.py: Adds %pydb magic when imported, for invoking the pydb enhanced debugger. 2006-10-23 Walter Doerwald