Debugging Python

May 29, 2007 at 02:36 PM | Python | View Comments

There are two modules that I use to debug Python code: pdb and rpdb2.

pdb

There are two main ways that I launch pdb: from the command line and from a breakpoint within a script.

To launch pdb from the command line, simply run Python with the -m pdb flag:

# py -m pdb script name

(if you're like me, python is a bit much to type... A simple fix is to just create a link to the python binary named py: ln -s $(which python) /usr/bin/py)

The second, and much more useful, method of invoking pdb is the set_trace function. To break at any point in your code, simply insert the line:

import pdb; pdb.set_trace()

When the code execution gets to that point, it will stop and drop you in to a debugging shell.
Just to feel cool like the Eclipse kids, I have mapped this to F8 in Vim (map <F8> Oimport pdb; pdb.set_trace() #BREAK<Esc>)

rpdb2

rpdb2 stands for Remote Python Debugger 2, and as the name suggests it allows remote debugging. This is useful if pdb does not play well with the threading/forking in your application (it did not like web.py, for example). The other, and much greater, benefit of rpdb2 is Winpdb. As the name suggests, Winpdb is a graphical Python debugger.

While Winpdb allows you to run your script from within the application, that is not very helpful if you are working on a beast like Drproject.

When you're working with a beastly application, it is much easier to set a rpdb2 breakpoint and then attach Winpdb to the application. To do this, stick this line where ever you want your application to break:

import rpdb2; rpdb2.start_embedded_debugger("asdf")

When your application gets to that line, it will "hang" as the debugger runs. Now it's time to fire up Winpdb and attach (File --> Attach) to the process. The password is "asdf". After it loads, you will be able to do debug the application like normal.

One final note about using rpdb2: to run a Python command (for instance, in the bottom right window of Winpdb), you have to prefix it with exec (for instance, exec print foo).