From 2e3f3b307d53f22cfda8a7c9052b355dfdaaf566 2012-07-23 20:16:41 From: Bradley M. Froehle Date: 2012-07-23 20:16:41 Subject: [PATCH] Merge pull request #2169 from bfroehle/ipdb_magics ipdb: Fix pdef, pdoc, pinfo commands. --- diff --git a/IPython/core/debugger.py b/IPython/core/debugger.py index 6af9c6f..fc8ac88 100644 --- a/IPython/core/debugger.py +++ b/IPython/core/debugger.py @@ -478,19 +478,20 @@ class Pdb(OldPdb): """The debugger interface to magic_pdef""" namespaces = [('Locals', self.curframe.f_locals), ('Globals', self.curframe.f_globals)] - self.shell.magic_pdef(arg, namespaces=namespaces) + self.shell.find_line_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)] - self.shell.magic_pdoc(arg, namespaces=namespaces) + self.shell.find_line_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)] - self.shell.magic_pinfo("pinfo %s" % arg, namespaces=namespaces) + self.shell.find_line_magic('pinfo')("pinfo %s" % arg, + namespaces=namespaces) def checkline(self, filename, lineno): """Check whether specified line seems to be executable. diff --git a/IPython/core/interactiveshell.py b/IPython/core/interactiveshell.py index b237df6..e11eef1 100644 --- a/IPython/core/interactiveshell.py +++ b/IPython/core/interactiveshell.py @@ -1487,7 +1487,7 @@ class InteractiveShell(SingletonConfigurable): """Generic interface to the inspector system. This function is meant to be called by pdef, pdoc & friends.""" - info = self._object_find(oname) + info = self._object_find(oname, namespaces) if info.found: pmethod = getattr(self.inspector, meth) formatter = format_screen if info.ismagic else None diff --git a/IPython/core/tests/test_debugger.py b/IPython/core/tests/test_debugger.py index 8e8a536..5dbc397 100644 --- a/IPython/core/tests/test_debugger.py +++ b/IPython/core/tests/test_debugger.py @@ -12,6 +12,8 @@ # Imports #----------------------------------------------------------------------------- +import sys + # third-party import nose.tools as nt @@ -19,6 +21,38 @@ import nose.tools as nt from IPython.core import debugger #----------------------------------------------------------------------------- +# Helper classes, from CPython's Pdb test suite +#----------------------------------------------------------------------------- + +class _FakeInput(object): + """ + A fake input stream for pdb's interactive debugger. Whenever a + line is read, print it (to simulate the user typing it), and then + return it. The set of lines to return is specified in the + constructor; they should not have trailing newlines. + """ + def __init__(self, lines): + self.lines = iter(lines) + + def readline(self): + line = next(self.lines) + print line + return line+'\n' + +class PdbTestInput(object): + """Context manager that makes testing Pdb in doctests easier.""" + + def __init__(self, input): + self.input = input + + def __enter__(self): + self.real_stdin = sys.stdin + sys.stdin = _FakeInput(self.input) + + def __exit__(self, *exc): + sys.stdin = self.real_stdin + +#----------------------------------------------------------------------------- # Tests #----------------------------------------------------------------------------- @@ -33,3 +67,57 @@ def test_longer_repr(): # in-place, since that global is used directly by the stdlib's pdb module. t = debugger.Tracer() nt.assert_equal(trepr(a), ar) + +def test_ipdb_magics(): + '''Test calling some IPython magics from ipdb. + + First, set up some test functions and classes which we can inspect. + + >>> class ExampleClass(object): + ... """Docstring for ExampleClass.""" + ... def __init__(self): + ... """Docstring for ExampleClass.__init__""" + ... pass + ... def __str__(self): + ... return "ExampleClass()" + + >>> def example_function(x, y, z="hello"): + ... """Docstring for example_function.""" + ... pass + + Create a function which triggers ipdb. + + >>> def trigger_ipdb(): + ... a = ExampleClass() + ... debugger.Pdb().set_trace() + + >>> with PdbTestInput([ + ... 'pdef example_function', + ... 'pdoc ExampleClass', + ... 'pinfo a', + ... 'continue', + ... ]): + ... trigger_ipdb() + --Return-- + None + > (3)trigger_ipdb() + 1 def trigger_ipdb(): + 2 a = ExampleClass() + ----> 3 debugger.Pdb().set_trace() + + ipdb> pdef example_function + example_function(x, y, z='hello') + ipdb> pdoc ExampleClass + Class Docstring: + Docstring for ExampleClass. + Constructor Docstring: + Docstring for ExampleClass.__init__ + ipdb> pinfo a + Type: ExampleClass + String Form:ExampleClass() + Namespace: Locals + File: ... + Docstring: Docstring for ExampleClass. + Constructor Docstring:Docstring for ExampleClass.__init__ + ipdb> continue + '''