Using pdb more effectively with Deferreds

How to be more productive using these built-in tools!

Debugging in twisted (or any framework with callbacks) is always a difficult task for the faint hearted. If you are a person who has relied heavily on IDE debuggers in the past, the verbosity of pdb can be scary at first. However there are a number of ways how you can make pdb work for you.

When people usually use the `import pdb; pdb.set_trace()` one liner they will stop the code execution and look around on values and exit. But there is more in the pdb toolhouse than just doing that.

$ <pdb> l
$ <pdb> l 30 # list the surrounding code

List is a really helpful tool. I usually forget the code that lies around my breakpoints so this is a helpful little reminder. The only gotcha with l is in the second variable.

$ <pdb> l 30,20 # list the code beginning from line 30 and add 20, until line 50.
$ <pdb> l 30,40 # list the code from line 30 to 40.

the second argument acts as an addition value if its less than the beginning line number but then acts as a ceiling when its larger than the beginning line.

$ <pdb> s # step into the function/method youre currently on

The step command helps you to step into the function in the frame. You could use this to step into function and stop at the first line in your function. However with deferreds this becomes quickly useless since you cannot step into a generator function using this method.

$ <pdb> unt # continue until a greater line or frame is reached

You could use this to step over for loops or recursions and continue execution until a greater line than your current one is reached.

$ <pdb> w # will shows the current frame and the previous frames

This command is especially useful when trying to put a break in a file but youre not exactly sure where. This lists all the files that the code executes and you can use these file names to quickly copy/paste to quickly navigate your code.

While not part of pdb, I believe the `locals()` command also should be honorably mentioned as the function displays the local variables in the current scope.

$ <pdb> cl
$ <pdb> cl inboxapi/handlers/campaigns/resources.py 123

The clear is especially useful for getting rid of all the breakpoints scattered around the code. I tend to place a lot of breakpoints, this comes in very handy when you dont specifically know where the breakpoint is.

Just so examples are more visual, we'll be using the above code as example.

$ <pdb> n # go to next line and dont execute

The `next` is a simple tool built for the simple debugger. The only gotcha here is that this doesn't work well with twisted architecture and generator functions. In these cases the frame will stop in twisteds deferred handlers rather than the function you want to go.

break usage 1

$ <pdb> break
$ <pdb> tbreak inboxapi/app.py:34

The break and temporary break (tbreak) are both essential tools for working with deferreds! These fix a lot of the framing issues with one struggles with the `s, n unt` commands. Points in the line of code that stop the execution of the code block and gives the user a pdb shell.

break usage 22

$ export PYTHONPATH=/your/project/dir:$PYTHONPATH

One gotcha with this tool is that you have to have your project folder on your `$PYTHONPATH` variable in your bash working environment or use fullpaths for the files. This can easily be done in any text editors contextual get filepath selection.

 

Comments