[top] [TitleIndex] [WordIndex]

10/480b/tab complete in python

Tab complete in Python

(Note: modified on 4/16/2010)

So as I've mentioned before in class, one of the nice features of Python is the ability to use tab completion to see what attributes and methods are available on an object. Stupidly, though, this isn't enabled by default in Python -- someone thought you'd actually want to use tab to indent. (Weirdos.) Anyway, here are some instructions for enabling it in various settings.

IPython

Nothing to do, tab completion just works.

Sage

Nothing to do, tab completion just works.

Python

Getting tab completion to work in Python isn't so bad, but it requires two steps. You can get tab completion to work simply by running a few commands at the >>> prompt -- but, of course, you don't want to have to do that every time. So you stick these commands in a file, then you set an environment variable to tell Python where to find that file. So first, let's make sure the set of commands we want to try is even going to work. Open up a Python session, and try this:

>>> import readline
>>> readline.parse_and_bind('tab: complete')
>>> readline.parse_and_bind('bind ^I rl_complete')
>>>

If any of those commands gives you an error, we're going to have to do a little extra work. If not, tab completion should just work at this point -- test it out by typing imp<TAB> (i.e. typing imp and hitting TAB). If it completes to import, we're off to the races. If it didn't work, you have a few choices. If you don't care about specifically using the Python command line directly, just install IPython and/or Sage. If you really want to use the Python command line directly, email me and ask for some more ideas. (In fact, if you're really interested -- in general you only need one of those two parse_and_bind commands. The second one is only there to make tab completion work with the MAC OSX version of readline, which is slightly different than the GNU one.)

Now let's say that worked, and you've got tab completion working in your current Python session. Now we just need to make that stick. We're going to make a new file in your home directory called .pythonrc, with the following contents:

#
# python startup script -- set up readline the way we like
#
# first version shamelessly stolen from:
#   http://docs.python.org/tutorial/interactive.html
#

import atexit, os, readline, rlcompleter

# set tab to autocomplete, which is far superior to, uh, tab. 
# we need different versions based on what architecture we're on.
if '/Frameworks/' in readline.__file__:
    # OSX readline
    readline.parse_and_bind('bind ^I rl_complete')
else:
    # otherwise assume GNU readline
    readline.parse_and_bind('tab: complete')

historyPath = os.path.expanduser("~/.pyhistory")

def save_history(historyPath=historyPath):
    import readline
    readline.write_history_file(historyPath)

try:
    if os.path.exists(historyPath):
        readline.read_history_file(historyPath)
except:
    print "Failed to import history file!"

atexit.register(save_history)
del os, atexit, readline, rlcompleter, save_history, historyPath

That actually does a bit more than just tab completion -- the extra business is there to save your command history between Python sessions. (Feel free to delete that part if you don't want it.) Now that you've got this saved in a file, we just need to tell Python where to find it at startup. Python will always check the location of the environment variable PYTHONSTARTUP and run that file, if it exists. So figure out the full path to the file we just created -- for me, it's /Users/craigcitro/.pythonrc, which is what I'll use. If you know all about environment variables, set this however you normally set your environment variables. If you've never heard of an environment variable before, edit the file .profile in your home directory and add the following contents:

PYTHONSTARTUP='/Users/craigcitro/.pythonrc'
export PYTHONSTARTUP

where, again, you replace the path to the file with wherever you put it on your machine.

Now you should be ready to rock and roll -- you need to exit your terminal and reopen it to make the changes take effect, but otherwise, this should work just fine. If not, drop me an email and tell me what went wrong.


2013-05-11 18:32