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

debugging with ipython does not work well outside ipython #57

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

debugging with ipython does not work well outside ipython #57

ipython opened this issue May 10, 2010 · 10 comments
Milestone

Comments

@ipython
Copy link
Collaborator

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
Copy link
Collaborator Author

ipython commented May 10, 2010

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

@ipython
Copy link
Collaborator Author

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
Copy link
Collaborator Author

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
Copy link
Collaborator Author

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
Copy link
Collaborator Author

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
Copy link
Collaborator Author

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
Copy link
Collaborator Author

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
Copy link
Collaborator Author

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
Copy link
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.

@nealmcb
Copy link

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.

minrk pushed a commit to minrk/ipython that referenced this issue Jul 1, 2013
Cleanup of format selection

Two small cleanups/fixes:

Much cleaner way of finding the right converter. This will result in much cleaner diffs when changing the API, adding arguments, etc. It also allows us to extract the known formats automatically.

Fixed an assertion which didn't actually check the file extension but an arbitrary occurrence of 'rst'
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants