I'm trying to extend the python shell (I can't use IPython, sadly). I'd like the ability to both keyword complete and interpret some custom input (that won't be valid python). But I can't get readline/rlcompleter and InteractiveConsole to work together. To demonstrate the problem:
$ python -c "import code; code.InteractiveConsole().interact()"
Python 2.7.10 (default, Jun 1 2015, 18:05:38)
[GCC 4.9.2] on cygwin
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>> import readline
>>> import rlcompleter
>>> readline.parse_and_bind("tab: complete")
>>> import string
>>> stri
Hitting tab here does nothing.
$ python
Python 2.7.10 (default, Jun 1 2015, 18:05:38)
[GCC 4.9.2] on cygwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import readline
>>> import rlcompleter
>>> readline.parse_and_bind("tab: complete")
>>> import string
>>> stri
Hitting tab now completes to "string".
Can anyone explain why this is and if there's a way around this?
OK - some digging around in the python source reveals the answer. The problem is that in InteractiveConsole
the namespace is set to something other than __main__
. But rlcompleter completes from builtins
and __main__
. Import string
above imports into the current namespace, which isn't __main__
and isn't searched by rlcompleter.
So, a solution is to construct your own rlcompleter.Completer and pass in the locals() to the ctor:
$ python -c "import code; code.InteractiveConsole().interact()"
Python 2.7.10 (default, Jun 1 2015, 18:05:38) [GCC 4.9.2] on cygwin
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>> import readline
>>> from rlcompleter import Completer
>>> readline.parse_and_bind("tab: complete")
>>> readline.set_completer(Completer(locals()).complete)
>>> import string
>>> str
str( string