Debugging Python/Django with PuDB
I’ve only been using this debugger for a little while, about six months, maybe a bit longer. Before that, I got by (or, I have to admit, struggled) with pdb, as well as print statements, logger, debug_toolbar, etc. The main difference is that PuDB has a graphical interface with syntax highlighting, panels for displaying additional information, IPython integration, handy hotkeys, and so on—all of which makes it an indispensable everyday tool!
Author: Andreas Klöckner
Project page on PyPI: http://pypi.python.org/pypi/pudb
Project source code on GitHub or in the author’s GitWeb
Current version: 2012.1
The debugger uses urwid to build its graphical interface and pygments for syntax highlighting.
Installation and configuration
It’s all very straightforward; install it from PyPI:
pip install pudb
Or from source:
git clone git://github.com/inducer/pudb.git
cd pudb && setup.py install
# либо сделайте симлинк в site-packages (я так обычно делаю, использую virtualenv и пакеты из транка)
ln -s ~/pudb/pudb ~/venv/<virtualenv>/lib/python2.7/site-packages/pudb
Launch PuDB:
$ python
>>> import pudb
>>> pudb.set_trace()
The debugger will appear and ask you to configure it. If it doesn’t, you can bring up the settings yourself—press “Ctrl+p”. There you can choose a shell (classic or ipython), a theme (classic, vim, dark vim, midnight, or create your own), the stack display order, and how to display the values of variables in the current context (type, str, repr, or your own implementation).
How to use it
I should point out right away that the interface makes it immediately clear what’s what, and if anything is unclear, press “?” to see the full help. I’ll give just part of it here, in order of how often I use it:
Basics:
! - open a shell, with the entire current context available o - show the console, but only for viewing; handy when you’ve entered something in the console and want to look at it again n - “step over”, move to the next line of code s - “step into”, go inside the object if possible; otherwise, move to the next line of code u - move up one stack frame d - move down one stack frame c - “continue”, continue execution (until the first breakpoint or until the program finishes) f - finish the current function q - exit the debugger and continue running the program e - show the traceback; you’ll first see a clear indication in the debugger’s header that a traceback has occurred L - show the path to the current file and the line number, as well as goto-line / - search for a string ("," - forward, “.” - backward)
Working with breakpoints:
b - set a breakpoint enter - edit a breakpoint (works in the Breakpoints panel) d - delete a breakpoint (works in the Breakpoints panel)
Working with panels:
V - switch to the Variables panel S - switch to the Stack panel B - switch to the Breakpoints panel +/- - increase/decrease the panel’s width _/= - minimize/maximize the panel’s width [/] - increase/decrease the panel’s height
Working with the Variables panel:
\ - expand/collapse a variable’s contents t/r/s/c - switch between the type/repr/str/custom variable display formats h - highlight a variable in the panel (also turns highlighting off) @ - pin a variable to the top of the panel w - switch to word-wrap mode for variables (and back again) n/Insert - add a watch expression to the top panel (for example, if you’re expecting a variable named “test_something” to appear, add its name; once it becomes available, it will appear in the top panel along with its value) enter - manage variables in Variables, including deleting them
Integration with Django and IPython
Before PuDB 2012.1, you had to take the following steps. If for some reason you’re using an older version of PuDB, this should come in handy. In the new version, there’s nothing to do; everything works out of the box!

There were also problems with IPython (version 0.13+) and PuDB versions before 2012.1, but if you’re using IPython 0.10.x (which is still the default version in Ubuntu’s packages), everything will be fine. Here’s something on PuDB+IPython integration, by the way.
Usage
Here are a couple of examples of how to use PuDB:
# Запуск отладчика для определенного скрипта
python -m pudb.run script.py
python -m pudb.run manage.py runcpdebug
# Далее, устанавливайте брейкпоинты и жмите "c" (Continue),
# как только отладчик дойдёт до брейкпоинта он остановится
You can invoke it in your code like this:
# В любом месте вставьте:
import pudb; pudb.set_trace()
On top of all that, here’s a screencast by the author:
Video / external material
PuDB Intro Screencast from Andreas Klöckner on Vimeo.
Implementing breakpoint setting for Emacs
Since I use Emacs, I decided to create a function and a hotkey for it to insert a PuDB breakpoint.
Put the following code in your “~/.emacs”:
(defun pudb-save-breakpoint ()
(interactive)
(setq file (buffer-file-name))
(setq line (substring (what-line) 5))
(setq saved-breakpoints "~/.config/pudb/saved-breakpoints")
(with-temp-buffer
(insert "b " file ":" line "\n")
(when (file-writable-p saved-breakpoints)
(append-to-file (point-min)
(point-max)
saved-breakpoints)))
)
(global-set-key [?\C-x ?\C-_] 'pudb-save-breakpoint)
The idea is simple: PuDB writes all its breakpoints to its own file, “~/.config/pudb/saved-breakpoints”, in this format:
b <file>:<line>
b <file>:<line>
As you can see, taking advantage of this is very easy—you just need to append breakpoints. You could also implement breakpoint deletion, clearing (including with a per-project namespace), and so on, but for now this is enough for me. If anyone knows of an existing module or wants to create a full-fledged Emacs+PuDB module, get in touch—I’d be delighted!
Since I’m not particularly good at elisp, another option is to write a Python script to which elisp would pass arguments, and have the script handle all the operations on the breakpoint file.
I also recommend taking a look at this list of Python debuggers: PythonDebuggers - PythonInfo Wiki.
Comments are closed. Read the original discussion in Russian →
