I make frequent use of python's built-in debugger, but one obvious feature seems to be missing - the bash-like tab completion that you can add to the interpreter. Fortunately pdb's interactive prompt is an instance of Cmd, so we can write our own completion function.
Note: this uses rlcompleter, which isn't available on windows
Edit (6 Jul 2009): import rlcompleter early and force output to stdout to ensure monkeypatch sticks Edit: updated to handle changes in local scope Edit: Fixed start via 'python -m pdb ...'. Check the comments for details.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
# save this in .pdbrc in your home directory import os import sys # import rlcompleter early, as it contains side effects import rlcompleter # refresh the terminal os.system("stty sane") # this rc file takes single lines, so define our complete function here execfile(os.path.expanduser("~/.pdbrc.py")) # replace the Pdb class's complete method with ours sys._getframe(1).f_globals['Pdb'].complete = complete # set use_rawinput to 1 as tab completion relies on rawinput being used sys._getframe(1).f_locals['self'].use_rawinput = 1 # save this in .pdbrc.py in your home directory def complete(self, text, state): """return the next possible completion for text, using the current frame's local namespace This is called successively with state == 0, 1, 2, ... until it returns None. The completion should begin with 'text'. """ # keep a completer class, and make sure that it uses the current local scope if not hasattr(self, 'completer'): self.completer = rlcompleter.Completer(self.curframe.f_locals) else: self.completer.namespace = self.curframe.f_locals return self.completer.complete(text, state)
Save the first part to a .pdbrc file in your home directory. If on startup pdb finds a .pdbrc file in either a user's home directory or in the current directory it runs each line as though it were typed into the prompt. Unfortunately that makes it impossible write multi-line functions in .pdbrc. So I have borrowed from http://wiki.python.org/moin/PdbRcIdea and used a separate file for the custom function that we want to do the real work.
When pdb starts, this replaces it's default completer function with that of rlcompleter before the completer function has been set. You should find that tab in pdb now completes names and provides proper object inspection, even as you move around the stack. pdb's default completer function only completes pdb commands, and most of those have single character abbreviations anyway. I got bored with typing "!dir([object])"
'complete' also tries to keep the completer class's namespace up to date, using curframe.f_locals.
If you would like to use tab completion, but not have it load for every session or reflect changes to the local scope then running:
import rlcompleter;import readline;readline.set_completer(rlcompleter.Completer(locals()).complete)
In a pdb prompt will enable tab completion. However, adding that to your .pdbrc file doesnt work as pdb seems to set its default completer function after the .pdbrc commands have been run.
Hope this saves you as much typing as me!
You need to import pdb in .pdbrc otherwise you get a pdb undefined error message.
hmm, even with that, I can't get tab completion to work. It's fine if I do readline.set_completer(rlcompleter.Completer(locals()).complete) manually, but the .pdbrc method fails. This is with python-2.4.3 on Gentoo.
python -m grabs our Pdb class! Thanks for the feedback. Here's what I think is going on:
tab completion works fine without the import provided you're stepping into your code with
However if you step in with "python -m pdb myscript.py" then python's pdb module creates an instance of the Pdb class before we can override it's complete function. Bummer.
This is fixed! Thanks for the comments. After a bit of testing I discovered that this wasn't working with 'python -m myscript.py' because we are changing the complete function on the Pdb class object in our current code block. However, running pdb via "python -m" uses execfile to start your script, and that is executed in a new code block. The side effect of this is that from .pdbrc.py the Pdb class object is not the one that is being used to run this pdb session. To get a reference to the original class object one needs to jump out of the current frame back to the frame that spawned this script. sys._getframe().f_back does that and f_globals['Pdb'] then grabs the origional Pdb class.
But why not use the package ipdb which provides many more things beyond tab completion?
Doesn't work for me, either to complete variables or members (after "."). Anyone got this working with python 2.6?
"L P", the reason is ipdb works only when run from within ipython, which is not always convenient.