27

I have been trying to get TAB to do something else than inserting a tab while at the (pdb) prompt.

What I have in mind is triggering autocomplete such as in here or here, but the tab key doesn't do anything else than adding tabs to pdb.

So with:

(pdb)var + tabKeyPressed

I'd want to get:

(pdb)variable

instead of:

(pdb)var[          ]
shx2
  • 61,779
  • 13
  • 130
  • 153
Rodrigo Lopez
  • 871
  • 10
  • 16
  • It seems to have been something with my Python installation, in a different computer both enclosed links worked like a charm. – Rodrigo Lopez Apr 13 '13 at 22:13

4 Answers4

28

The iPython is third-party solution for this problem. Sometimes you can only rely on vanilla Python. I found 2 solutions for it.

Per-shell solution - usage module 'rlcompleter':

$ python3

Python 3.4.3 (default, Sep 14 2016, 12:36:27) 
[GCC 4.8.4] on linux
Type "help", "copyright", "credits" or "license" for more information.

>>> import pdb
>>> pdb.set_trace()
--Return--
> <stdin>(1)<module>()->None

# press tab - but nothing
(Pdb) str.
*** SyntaxError: invalid syntax
(Pdb) --KeyboardInterrupt--
(Pdb) c
>>> import rlcompleter
>>> pdb.Pdb.complete=rlcompleter.Completer(locals()).complete
>>> pdb.set_trace()
--Return--
> <stdin>(1)<module>()->None
(Pdb) str.
str.__add__(            str.__getattribute__(   str.__name__            str.__text_signature__  str.isdigit(            str.rfind(
str.__base__(           str.__getitem__(        str.__ne__(             str.__weakrefoffset__   str.isidentifier(       str.rindex(
str.__bases__           str.__getnewargs__(     str.__new__(            str.capitalize(         str.islower(            str.rjust(
str.__basicsize__       str.__gt__(             str.__prepare__(        str.casefold(           str.isnumeric(          str.rpartition(
str.__call__(           str.__hash__(           str.__qualname__        str.center(             str.isprintable(        str.rsplit(
str.__class__(          str.__init__(           str.__reduce__(         str.count(              str.isspace(            str.rstrip(
str.__contains__(       str.__instancecheck__(  str.__reduce_ex__(      str.encode(             str.istitle(            str.split(
str.__delattr__(        str.__itemsize__        str.__repr__(           str.endswith(           str.isupper(            str.splitlines(
str.__dict__            str.__iter__(           str.__rmod__(           str.expandtabs(         str.join(               str.startswith(
str.__dictoffset__      str.__le__(             str.__rmul__(           str.find(               str.ljust(              str.strip(
str.__dir__(            str.__len__(            str.__setattr__(        str.format(             str.lower(              str.swapcase(
str.__doc__             str.__lt__(             str.__sizeof__(         str.format_map(         str.lstrip(             str.title(
str.__eq__(             str.__mod__(            str.__str__(            str.index(              str.maketrans(          str.translate(
str.__flags__           str.__module__          str.__subclasscheck__(  str.isalnum(            str.mro(                str.upper(
str.__format__(         str.__mro__             str.__subclasses__(     str.isalpha(            str.partition(          str.zfill(
str.__ge__(             str.__mul__(            str.__subclasshook__(   str.isdecimal(          str.replace(            
(Pdb) c
>>>

System-wide solution - usage file ~/.pdbrc

$ cat ~/.pdbrc
import rlcompleter
pdb.Pdb.complete=rlcompleter.Completer(locals()).complete
$ python3
Python 3.4.3 (default, Sep 14 2016, 12:36:27) 
[GCC 4.8.4] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import pdb
>>> pdb.set_trace()
--Return--
> <stdin>(1)<module>()->None
(Pdb) str.
str.__add__(            str.__getattribute__(   str.__name__            str.__text_signature__  str.isdigit(            str.rfind(
str.__base__(           str.__getitem__(        str.__ne__(             str.__weakrefoffset__   str.isidentifier(       str.rindex(
str.__bases__           str.__getnewargs__(     str.__new__(            str.capitalize(         str.islower(            str.rjust(
str.__basicsize__       str.__gt__(             str.__prepare__(        str.casefold(           str.isnumeric(          str.rpartition(
str.__call__(           str.__hash__(           str.__qualname__        str.center(             str.isprintable(        str.rsplit(
str.__class__(          str.__init__(           str.__reduce__(         str.count(              str.isspace(            str.rstrip(
str.__contains__(       str.__instancecheck__(  str.__reduce_ex__(      str.encode(             str.istitle(            str.split(
str.__delattr__(        str.__itemsize__        str.__repr__(           str.endswith(           str.isupper(            str.splitlines(
str.__dict__            str.__iter__(           str.__rmod__(           str.expandtabs(         str.join(               str.startswith(
str.__dictoffset__      str.__le__(             str.__rmul__(           str.find(               str.ljust(              str.strip(
str.__dir__(            str.__len__(            str.__setattr__(        str.format(             str.lower(              str.swapcase(
str.__doc__             str.__lt__(             str.__sizeof__(         str.format_map(         str.lstrip(             str.title(
str.__eq__(             str.__mod__(            str.__str__(            str.index(              str.maketrans(          str.translate(
str.__flags__           str.__module__          str.__subclasscheck__(  str.isalnum(            str.mro(                str.upper(
str.__format__(         str.__mro__             str.__subclasses__(     str.isalpha(            str.partition(          str.zfill(
str.__ge__(             str.__mul__(            str.__subclasshook__(   str.isdecimal(          str.replace(            
(Pdb) c
>>> 

Notes:

  1. Tested only on the Python 3.4

  2. OS - Linux Mint

  3. Based on https://reminiscential.wordpress.com/2009/06/12/python-enable-auto-complete-in-a-pdb-session/

PADYMKO
  • 4,217
  • 2
  • 36
  • 41
  • 2
    To use invoke pdb with `python -m pdb script.py`, you should also `import pdb` in `.pdbrc`. – jdhao Jan 10 '19 at 13:59
  • I am using the .pdbrc. My python3.7 installation was missing gnureadline. So in case this approach won't work try a `pip install gnureadline` – tharndt Aug 28 '19 at 15:14
  • what about jupyter notebooks? does it makes sense, given that `tabKeyPressed` actually moves the focus to the next cell? (if for instance I use %%debug) – thanks! – jjrr Jun 30 '20 at 11:32
  • FYI, this answer is for the GNU readline. For NetBSD, see [my answer](https://stackoverflow.com/a/76766050/20307768). – Constantin Hong Jul 25 '23 at 21:03
15

ipdb to the rescue.

ipdb exports functions to access the IPython debugger, which features tab completion, syntax highlighting, better tracebacks, better introspection with the same interface as the pdb module.

shx2
  • 61,779
  • 13
  • 130
  • 153
  • 2
    I did try it for a while, and it did deliver the goods. I am just not very fond of it. – Rodrigo Lopez Apr 12 '13 at 22:22
  • @RodrigoLopez: What do you use/do instead? – danuker May 04 '18 at 13:24
  • PDB autocomplete ended up working (something was off in my installation). PDB did the job (today I'd probably use VSC, tbh) – Rodrigo Lopez May 07 '18 at 08:58
  • about half the time ipdb doesn't work for my use case (it crashes with meaningless errors that don't return any google results, and I don't have the time to debug my debugger when I'm trying to debug code) – vlsd Dec 05 '19 at 18:52
  • 1
    @vlsd, I have been using ipdb for years, with no crashes. – shx2 Dec 05 '19 at 18:58
  • @shx2 that's wonderful, but it doesn't change my experience; ipdb is great in terms of features, but the main reason I came to this thread in the first place was because it's easier to turn on a feature in a standard debugger than try to debug a third party one – vlsd Feb 12 '20 at 18:27
11

Official documents said:

Changed in version 3.3: Tab-completion via the readline module is available for commands and command arguments, e.g. the current global and local names are offered as arguments of the p command.

https://docs.python.org/3/library/pdb.html

So you just using p command:

(Pdb) p var[TAB] # complete global and local names
var1 var2
(Pdb) [TAB] # complete commands
EOF        b          cl         cont       disable    exit       interact   list       next       quit       retval     source     unalias    up         
a          break      clear      continue   display    h          j          ll         p          r          run        step       undisplay  w          
alias      bt         commands   d          down       help       jump       longlist   pp         restart    rv         tbreak     unt        whatis     
args       c          condition  debug      enable     ignore     l          n          q          return     s          u          until      where 
eshizhan
  • 4,235
  • 2
  • 23
  • 23
  • 1
    this is nice! can verify worked in python 3.7.1 – jmunsch Apr 14 '21 at 06:21
  • Thanks. for clarification: when you enter a variable name on the Pdb repl, it will print its content, but won't let you autocomplete, if you use the `p` command of `Pdb`, which basically used for the same usecase, you will get autocompletion. – YuvalHelman Mar 03 '22 at 09:45
  • I think this solution should be upvoted as it doesn't require a user to install a third-party tool. All the user needs to do is to prefix a variable with "p [space] "and it will autocomplete the variable name, it also shows the object's functions and variables. (eg: after importing sys, p sys.[tab] will show all the functions and variables of sys object) – EuWern Oct 12 '22 at 13:35
0

If you use macOS with NetBSD libedit(default) or your Python is not compiled with GNU readline lib but Net BSD libedit, insert python:bind ^I rl_complete in ~/.editrc. In this case, ^I has two characters.(^ and I)

Also, you have to remove the GNU readline solutions you tried. e.g. some part in ~/.pdbrc(or ./.pdbrc) or rlcompleter of the answer.

Constantin Hong
  • 701
  • 1
  • 2
  • 16