debugging with ipython does not work well outside ipython #57

Closed
ipython opened this Issue May 10, 2010 · 10 comments

Projects

None yet

3 participants

@ipython
ipython commented May 10, 2010

Original Launchpad bug 412396: https://bugs.launchpad.net/ipython/+bug/412396
Reported by: cimrman3 (Robert Cimrman).

Python 2.5.4, IPython 0.9.1, gentoo linux

The Tracer does not work outside ipython, short summary follows below, for details see the thread [1].

[1] http://mail.scipy.org/pipermail/ipython-user/2009-July/006451.html

When running the attachment file ipython_debug1.py:

  $ python ipython_debug1.py
Traceback (most recent call last):
   File "ipython_debug1.py", line 6, in <module>
     debug = Tracer()
   File "/usr/lib64/python2.5/site-packages/IPython/Debugger.py", line
135, in __init__
     self.debugger = Pdb(colors)
   File "/usr/lib64/python2.5/site-packages/IPython/Debugger.py", line
213, in __init__
     self.color_scheme_table = ExceptionColors.copy()
   File "/usr/lib64/python2.5/site-packages/IPython/ColorANSI.py", line
151, in copy
     return ColorSchemeTable(self.values(),self.active_scheme_name)
   File "/usr/lib64/python2.5/site-packages/IPython/ColorANSI.py", line
144, in __init__
     raise ValueError,'you must specify the default color scheme'
ValueError: you must specify the default color scheme

The second file ipython_debug2.py performs better - the debugging is actually possible, but any exception after the 'continue' command causes the ipython crash dump:

$ python ipython_debug2.py
hello
 > ipython_debug2.py(14)<module>()
      13
---> 14 print 'hello again'
      15

ipdb>

then type 'c' to continue, and you get the error. I would like to see
just the ZeroDivisionError, not the ipython crash dump that follows.

@ipython
ipython commented May 10, 2010

[ LP comment 1 by: Robert Cimrman, on 2009-08-12 08:40:53.292770+00:00 ]

@ipython
ipython commented May 10, 2010

[ LP comment 2 by: Fernando Perez, on 2010-04-26 06:07:25.063351+00:00 ]

I'm afraid that for now, IPython's debugger is pretty much welded to living inside a 'real ipython'. It simply assumes in too many places that the ipython machinery is already up and running.

It would be definitely great to decouple them, but it's a fairly non-trivial job. I'm marking this as a wishlist item so we don't forget about it, but I don't think it will happen soon, unfortunately.

@ipython
ipython commented May 10, 2010

[ LP comment 3 by: Robert Cimrman, on 2010-04-26 07:43:56.257570+00:00 ]

Thanks Fernando.

As a workaround, is there a way to capture/silence/redirect to /dev/null somehow the ipython crash report output after pressing Ctrl-C? The crash per se does not matter, it's just the length of the output, that makes the interesting things I saw while debugging to scroll out of sight (and often even the terminal buffer).

@ipython
ipython commented May 10, 2010

[ LP comment 4 by: Fernando Perez, on 2010-04-27 05:41:20+00:00 ]

Hi Robert,

On Mon, Apr 26, 2010 at 12:43 AM, Robert Cimrman cimrman3@ntc.zcu.cz wrote:

Thanks Fernando.

As a workaround, is there a way to capture/silence/redirect to /dev/null
somehow the ipython crash report output after pressing Ctrl-C? The crash
per se does not matter, it's just the length of the output, that makes
the interesting things I saw while debugging to scroll out of sight (and
often even the terminal buffer).

Certainly, I suspect the problem is that ipython sets sys.excepthook
to be its own (noisy) crash handler.

Just save sys.excepthook before you start ipython's machinery to
sys.old_excepthook, and restore it immediately once you exit the
ipython part and you shouldn't see the ipython internal handler
anymore.

Let me know if that works for you.

Cheers,

f

@ipython
ipython commented May 10, 2010

[ LP comment 5 by: Robert Cimrman, on 2010-04-27 11:30:33+00:00 ]

On 04/27/10 07:41, Fernando Perez wrote:

Hi Robert,

On Mon, Apr 26, 2010 at 12:43 AM, Robert Cimrmancimrman3@ntc.zcu.cz wrote:

Thanks Fernando.

As a workaround, is there a way to capture/silence/redirect to /dev/null
somehow the ipython crash report output after pressing Ctrl-C? The crash
per se does not matter, it's just the length of the output, that makes
the interesting things I saw while debugging to scroll out of sight (and
often even the terminal buffer).

Certainly, I suspect the problem is that ipython sets sys.excepthook
to be its own (noisy) crash handler.

Just save sys.excepthook before you start ipython's machinery to
sys.old_excepthook, and restore it immediately once you exit the
ipython part and you shouldn't see the ipython internal handler
anymore.

Let me know if that works for you.

Perfect! I will use the following function:

def debug():
try:
old_excepthook = sys.excepthook
import ipdb as pdb
sys.excepthook = old_excepthook

 except:
     import pdb

 pdb.set_trace()

Do you happen to know how to avoid pressing 'n' to get to the caller's frame?

cheers,
r.

@ipython
ipython commented May 10, 2010

[ LP comment 6 by: Fernando Perez, on 2010-04-27 17:22:46+00:00 ]

Hi Robert,

On Tue, Apr 27, 2010 at 4:30 AM, Robert Cimrman cimrman3@ntc.zcu.cz wrote:

Perfect! I will use the following function:

Great, glad it worked.

Do you happen to know how to avoid pressing 'n' to get to the caller's
frame?

No idea, sorry.

Cheers,

f

@ipython
ipython commented May 10, 2010

[ LP comment 7 by: Robert Cimrman, on 2010-04-28 08:04:39+00:00 ]

On 04/27/10 19:22, Fernando Perez wrote:

Hi Robert,

On Tue, Apr 27, 2010 at 4:30 AM, Robert Cimrmancimrman3@ntc.zcu.cz wrote:

Perfect! I will use the following function:

Great, glad it worked.

Do you happen to know how to avoid pressing 'n' to get to the caller's
frame?

No idea, sorry.

I have a working solution now, see below. The only problem is, that sphinx'
automodule directive ignores the returned debug() function, but this problem
can be solved by adding it directly using autofunction:

.. automodule:: my_module
:members:
:undoc-members:

.. autofunction:: my_module.debug

In my_module:

def get_debug():
"""
Utility function providing debug() function.
"""
old_excepthook = sys.excepthook

 try:
     import ipdb
 except ImportError:
     debug = None
 else:
     debug = ipdb.set_trace

 if debug is None:
     try:
         from IPython.Debugger import Pdb
         from IPython.Shell import IPShell
         from IPython import ipapi
     except ImportError:
         pass
     else:
         shell = IPShell(argv=[''])
         def debug():
             ip = ipapi.get()
             def_colors = ip.options.colors
             Pdb(def_colors).set_trace(sys._getframe().f_back)

 if debug is None:
     import pdb
     debug = pdb.set_trace

 sys.excepthook = old_excepthook

 debug.__doc__ = """
 Start debugger on line where it is called, roughly equivalent to::

     import pdb; pdb.set_trace()

 First, this function tries to use `ipdb` (`IPython`-enabled `pdb`).

 If it is not installed, the function resorts to trying to start the
 debugger directly using the `IPython` API.

 When this fails too, the plain old `pdb` is used instead.
 """

 return debug

debug = get_debug()

cheers,
r.

@ipython
ipython commented May 10, 2010

[ LP comment 8 by: Fernando Perez, on 2010-04-28 17:42:05.185350+00:00 ]

OK, great. This bug stays tagged as wishlist, so we can effectively provide something like what you are doing, with a publicly supported api.

@fperez
Member
fperez commented Nov 28, 2011

This has now been fixed, though the api is minimally different:

from IPython.core.debugger import Tracer
debug = Tracer()

print 'hello'

debug()

print 'hello again'

1/0

If the above is put in a file, it works as expected. Closing.

@fperez fperez closed this Nov 28, 2011
@nealmcb
nealmcb commented Jun 17, 2013

Thanks.

I got this error message:

ImportError: "No module named Debugger"

when using the previous idiom:
from IPython.Debugger import Tracer; debug_here = Tracer()

and the new api you note in #57 (comment) is just what I was looking for. Hopefully this will help other searchers find it quickly.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment