Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ipdb: pdef, pdoc, pinfo magics all broken #2169

Merged
merged 3 commits into from Jul 23, 2012
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
7 changes: 4 additions & 3 deletions IPython/core/debugger.py
Expand Up @@ -478,19 +478,20 @@ def do_pdef(self, arg):
"""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)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note that we cannot use self.shell.run_line_magic since we need to pass the namespaces parameter along.


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,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why did you decide to make the call this way and not with the higher-level run_line_magic method?

namespaces=namespaces)

def checkline(self, filename, lineno):
"""Check whether specified line seems to be executable.
Expand Down
2 changes: 1 addition & 1 deletion IPython/core/interactiveshell.py
Expand Up @@ -1479,7 +1479,7 @@ def _inspect(self, meth, oname, namespaces=None, **kw):
"""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
Expand Down
88 changes: 88 additions & 0 deletions IPython/core/tests/test_debugger.py
Expand Up @@ -12,12 +12,46 @@
# Imports
#-----------------------------------------------------------------------------

import sys

# third-party
import nose.tools as nt

# Our own
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
#-----------------------------------------------------------------------------
Expand All @@ -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
> <doctest ...>(3)trigger_ipdb()
1 def trigger_ipdb():
2 a = ExampleClass()
----> 3 debugger.Pdb().set_trace()
<BLANKLINE>
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
'''