Breakpoint-induced interactive debugging of Python with IPython

Question:

Say I have an IPython session, from which I call some script:

> run my_script.py

Is there a way to induce a breakpoint in my_script.py from which I can inspect my workspace from IPython?

I remember reading that in previous versions of IPython one could do:

from IPython.Debugger import Tracer;     

def my_function():
    x = 5
    Tracer()
    print 5;

but the submodule Debugger does not seem to be available anymore.

Assuming that I have an IPython session open already: how can I stop my program a location of my choice and inspect my workspace with IPython?

In general, I would prefer solutions that do not require me to pre-specify line numbers, since I would like to possibly have more than one such call to Tracer() above and not have to keep track of the line numbers where they are.

Answers:

Inside the IPython shell, you can do

from IPython.core.debugger import Pdb
pdb = Pdb()
pdb.runcall(my_function)

for example, or do the normal pdb.set_trace() inside your function.

Answered By: Daniel Roseman

You can run it and set a breakpoint at a given line with:

run -d -b12 myscript

Where -b12 sets a breakpoint at line 12. When you enter this line, you’ll immediately drop into pdb, and you’ll need to enter c to execute up to that breakpoint.

Answered By: Wilduck

I have always had the same question and the best workaround I have found which is pretty hackey is to add a line that will break my code, like so:

...
a = 1+2
STOP
...

Then when I run that code it will break, and I can do %debug to go there and inspect. You can also turn on %pdb to always go to point where your code breaks but this can be bothersome if you don’t want to inspect everywhere and everytime your code breaks. I would love a more elegant solution.

Answered By: dvreed77

The Tracer() still exists in ipython in a different module. You can do the following:

from IPython.core.debugger import Tracer

def my_function():
    x = 5
    Tracer()()
    print 5

Note the additional call parentheses around Tracer

edit: For IPython 6 onwards Tracer is deprecated so you should use set_trace() instead:

from IPython.core.debugger import set_trace

def my_function():
    x = 5
    set_trace()
    print 5
Answered By: pankaj

This is the version using the set_trace() method instead of the deprecated Tracer() one.

from IPython.core.debugger import Pdb

def my_function():
    x = 5
    Pdb().set_trace()
    print 5
Answered By: Medhat Omr

With Python 3 (v3.7+), there’s the new breakpoint() function. You can modify it’s behaviour so it’ll call ipython’s debugger for you.

Basically you can set an environment variable that points to a debugger function. (If you don’t set the variable, breakpoint() defaults to calling pdb.)

To set breakpoint() to call ipython’s debugger, set the environment variable (in your shell) like so:

# for bash/zsh users
export PYTHONBREAKPOINT='IPython.core.debugger.set_trace'
# powershell users
$env:PYTHONBREAKPOINT='IPython.core.debugger.set_trace'

(Note, obviously if you want to permanently set the environment variable, you’ll need to modify your shell profile or system preferences.)

You can write:

def my_function():
    x = 5
    breakpoint()
    print 5;

And it’ll break into ipython’s debugger for you. I think it’s handier than having to import from IPython.core.debugger import set_trace and call set_trace().

Answered By: Donal

I see a lot of options here, but maybe not the following simple option.
Fire up ipython in the directory where my_script.py is.
Turn the debugger on if you want the code to go into debug mode when it fails. Type %pdb.

In [1]: %pdb
Automatic pdb calling has been turned ON

Next type

In [2]: %run -d ./my_script.py
*** Blank or comment
*** Blank or comment
NOTE: Enter 'c' at the ipdb>  prompt to continue execution.
> c:usersc81196lgdmortgages-1nmblgdrun_lgd.py(2)<module>()
      1 # system imports
----> 2 from os.path import join

Now you can set a breakpoint where ever you want it.
Type b 100 to have a breakpoint at line 100, or b whatever.py:102 to have a breakpoint at line 102 in whatever.py.
For instance:

ipdb> b 100

Then continue to run, or continue.

ipdb> c

Once the code fails, or reaches the breakpoint you can start using the full power of the python debugger pdb.

Note that pdb also allows the setting of a breakpoint at a function.

b(reak) [([filename:]lineno | function) [, condition]]

So you do not necessarily need to use line numbers.

Answered By: vaudt