The Python Debugger (pdb) is a powerful tool that all Python developers should be familiar with. It's an interactive debugger that you can start up anywhere in your codebase. This makes debugging complex or confusing code much simpler since you can interact directly with the code in a running state.
There are just a few basic pdb commands you need to know in order to start being productive. If you want more info, you can always look at the internal help:
(Pdb) help
(Pdb) help list
The most basic commands you will need are list
, next
, step
and continue
. This will allow you to do basic navigation of the debugging session so you can figure out what is happening in the code.
The easiest way to invoke pdb is to add a set_trace
in your code. Here is an example:
import pdb; pdb.set_trace()
This is a PEP8 violation, but you should never check this code in, so we won't worry about that.
Another way is to invoke the pdb module from the command line.
$ python -m pdb mycode.py
Choose the method that works best for your situation. We will use the command line method to see how pdb works in the next section.
Here is an example of a debugging session with pdb:
$ python -m pdb example.py
> example.py(1)<module>()
-> my_string = 'one'
(Pdb) next
1 -> my_string = 'one'
2 my_other_string = 2
3
4 print my_string + my_other_string
> example.py(2)<module>()
-> my_other_string = 2
(Pdb) next
(Pdb) next
1 my_string = 'one'
2 my_other_string = 2
3
4 -> print my_string + my_other_string
TypeError: "cannot concatenate 'str' and 'int' objects"
Now we are stopped at the line that has the error on it and can inspect the current state of things further.
> example.py(4)<module>()
-> print my_string + my_other_string
(Pdb) type(my_string)
<type 'str'>
(Pdb) type(my_other_string)
<type 'int'>
(Pdb) my_other_string
2
Now, what if I try some alternatives?
(Pdb) print my_string + '2'
one2
(Pdb) print my_string + str(my_other_string)
one2
(Pdb) print '{}{}'.format(my_string, my_other_string)
one2
This gives you a chance to find out what will actually work when you are in this situation. Then you can go modify your code, run your tests and get that bug fixed!
There are a few different implementations out there that build upon pdb. These replacements typically enhance the experience by adding things like tab completion and syntax highlighting. My favorite is pdb++ because it has a sticky_by_default
option that shows the whole context of the code as you step through it, eliminating the need to use the list
command in most cases.
Another alternative is ipdb, which embeds an IPython interpreter as the pdb prompt. If you've ever used IPython, then you know how powerful it can be. Now you can have that power in the debugger.
One main difference between these two alternatives is that ipdb uses a separate import to do a set_trace
in the code. Whereas pdb++ overrides the standard set_trace
to invoke itself. This makes dropping in pdb++ into your project a seamless operation.