PuDB, a better Python debugger

So Christian Muise unwittingly just reminded me on IRC that I forgot to mention the main method that I used to learn how the heurisch function works in my last blog post. I usually only use a debugger when I have a really hard bug I need to figure out, when the print statements aren’t enough. The reason for this is that the debugger that I had been using, winpdb, is, well, a pain to use. There are so many little bugs, at least in Mac OS X, that it is almost not worth while to use it unless I need to. For example, restarting a script from the debugger doesn’t work. If I pass a point that I wanted to see, I have to completely close the winpdb window and restart it from the command line, which takes about half a minute. Also, winpdb uses it’s own variant of pdb, which seems to cause more problems than it creates (like bugging me about sympy importing pdb somewhere every time I start debugging.)

But I really wanted to be able to step through the heurisch code to see exactly how it works, because many of the implementation details, such as gathering the components of an expression, will be similar if not exactly the same in the full algorithm. So I started my quest for a better debugger. For me, the ideal debugger is the C debugger in XCode. That debugger has saved me in most of my programming assignments in C. But it is only for C based languages (C, Objective-C, probably C++, …), not Python. So I did a Google search, and it turns out that there is a list of Python debuggers here. So I went through them, and I didn’t have to go far. The very first one, pudb, turns out to be awesome!

You can watch this screencast to get a better idea of the features, or even better install it and check them out. The debugger runs in the console, not in some half-hacked GUI (half-hacked is what any non-Cocoa GUI looks like in Mac OS X). The only down side to this is that you have to use the keyboard to do everything, but it ends up not being too bad. And you can press ‘?’ at any time to see the possible commands.

To install it, just do easy_install pudb. To run it, just create a script of what you want to debug, and do python -m pudb.run my-script.py and it just works! I have a line that says alias pudb='python -m pudb.run' in my .profile, which makes it even easier to run. If you want to set a break point in the code, you can either navigate there from within pudb by pressing ‘m’, or you add a line that says from pudb import set_trace; set_trace() to the code (if you add the line to your code, you don’t even need to create a script. Just execute the code in IPython and when it hits that line, it will load the debugger).

Some cool features:

– IPython console. Just press ‘!’ to go to a console, where you can manipulate variables from the executed namespace, and you can choose an IPython console.

– Very easy to navigate. You just need to know the keys ‘s’, ‘n’, and ‘t’.

– View the code from elsewhere than what is being run. Pressing ‘m’ lets you view all imported modules. You can easily view points on the stack by choosing them.

– If an exception is thrown, it catches it! This may sound obvious for a debugger, but it is one of things that didn’t work very well in winpdb. You can view the traceback of the exception, and choose to restart without having to close and reopen the debugger. Actually, it asks you if you want to restart every time the script finishes too, which is also a great improvement over winpdb.

This is what it looks like. Click for a bigger picture:

This is where the heurisch algorithm hangs.

Some annoyances (in case Andreas Kloeckner reads this):

– The default display for variables is type, which is completely useless. I have to manually go through and change each to str so I can see what the variable is. Is there a way to change this default?

– It asks me every time if I want to use IPython. I always want to use IPython.

– This is might be a Mac OS X Terminal bug, but when I execute a statement that takes a while to run, it doesn’t redraw the pudb window until it finishes. This means that stepping through a program “flashes” black from what is above pudb in the window, and if I run a statement that takes forever, I loose the ability to see where it is unless I keyboard interrupt. Fortunately, it catches keyboard interrupts, so I can still see the traceback.

– There is no way to resize the variables window, or to scroll sideways in it. If I want to see what a long variable expression is, I have to go to the IPython console and type it there.

Some of these might be fixable and I just don’t know it yet. But even with them, this is still an order of magnitude improvement over winpdb. Now I can actually use the debugger all the time in my coding, instead of just when I have a really tough bug and no other choice.

UPDATE:

The first two were trivial to fix in a fork of the repository (isn’t open source awesome?). So if those are bothering you too, check out my branches at http://github.com/asmeurer/PuDB. Maybe if I have some time I will make them global options using environment variables or something and see if Andreas wants to merge them back into the main repo.

As for the second one, I realized that it might be a good thing, because you can see anything that is printed. Still, I would prefer seeing both, if possible (and the black flashes are annoying).

UPDATE 2:

You can resize the side view by pushing +/-, though there doesn’t seem to be a way to, say, make the variables view bigger and the breakpoints view smaller.

UPDATE 3:

A while back Ondrej modified the code to have a different color theme, and I followed suit. See this conversation at GitHub. So now, instead of looking like a DOS terminal, in PuDB for me looks like this:

PuDB XCode Midnight Theme Colors

PuDB XCode Midnight Theme Colors

This is exactly the same colors as my code in XCode, the editor I use, with the Midnight Theme. It’s pretty easy to change the colors to whatever you want. Right now, you have to edit the source, but Ondrej or I might someday make it so you can have themes.

Also, having used this all summer (and it was a life-saver having it in multiple occasions, and I am sure made my development speed at least twice as fast in others), I have one additional gripe. It is too difficult to arrow up to the variable that you want to access in the variables view. It would be nice to have a page up/page down feature there.

UPDATE 4: PuDB has since improved a lot, include many fixes by myself. It now supports themes, saved settings, variable name wrapping, and more. See this followup post.

12 Responses to PuDB, a better Python debugger

  1. Ted Horst says:

    Hi Aaron,

    Thanks for the tip about pudb. It looks nice, but I can’t figure out the most basic thing, how do I get back to the source view after I have navigated to another view?

    Sorry to ask you about this, but I can’t find it in the docs and there doesn’t seem to be a mailing list.

    Thanks,
    Ted

    • asmeurer says:

      Hi Ted.

      It tells you, at least for IPython. Just press Control-D! :)

      Aaron Meurer

      EDIT:
      Or are you talking about navigating the stack and variables? Just use the arrow keys (press ? to see more).

      • Ted Horst says:

        Arrow keys it is. Still don’t see that in the help, but seems obvious now as I was already using up/down arrows.

        Thanks!

        • asmeurer says:

          Ah, I guess it isn’t. I think there isn’t a mailing list because it is just the one developer who made it. The source isn’t too hard to modify (git clone http://git.tiker.net/trees/pudb.git), so you could probably go in and add a shortcut to go back to the source view.

        • thomas says:

          Many thanks, also didn’t occur to be to use horiz. arrow keys.

  2. PuDB is quite nice and all, but I find it a bit too jarring to jump from TextMate all the way to a text mode program (and is it only for me it blinks every time you step?).

    So I got a little carried away and thought I’d code a basic debugger for TextMate. I present to you PythonMate: https://github.com/boxed/PythonMate

    It has some rather sharp edges in the current state but I’ll continue polishing it up as I need to use it. I would of course appreciate any help a lot! (For example, it could need stop/restart/etc functionality :P )

    • Aaron Meurer says:

      No, it blinks for me too. See the third annoyance above.

      I don’t use TextMate to edit code (I use XCode), and I am always using the terminal to test the code, so having a terminal debugger like PuDB isn’t that bad for me.

  3. […] of this blog may remember last year when I wrote about this awesome visual console Python debugger called PuDB. I suggest you read that post if you […]

  4. Victor Eijkhout says:

    How do I invoke these themes? I have whatever pudb install I got from macports and that’s about all I know. It works great but it’s ugly.

    • asmeurer says:

      I think the macports version may be out of date. Try doing a “pip install pudb”, or you can just do “git clone https://github.com/inducer/pudb.git; ./setup.py develop” to run the development version. Once you’ve upgraded, it should show you the prefs dialog on the first run, which has the themes. Or you can press Ctrl-p to bring it up at any time.

  5. […] when I debug SymPy code with PuDB, I create a script that calls the code, then I put […]

  6. Johnny says:

    “though there doesn’t seem to be a way to, say, make the variables view bigger and the breakpoints view smaller.”

    There is in recent versions. Use the [ and ] keys.

Leave a reply to asmeurer Cancel reply