python autocompletion to replay file interactively

When teaching python it is helpful to be able to replay a script. The .pythonstartuprc below checks for whether or not PYTHON_REPLAY_FILE is in your env and points to a valid file. If it does, then it creates a readline completer that fills in the next line of the file when you hit <TAB%gt; from a blank line. The object will be in your locals as _completer and you can use _completer.list() to see the sections, and _completer.seek(10) or _completer.seek(section_name) to jump around in your tutorial (skipped code will NOT be executed).

# Store the file in ~/.pystartup, and set an environment variable to point
# to it:  "export PYTHONSTARTUP=/max/home/itamar/.pystartup" in bash.
#
# Note that PYTHONSTARTUP does *not* expand "~", so you have to put in the
# full path to your home directory.
 
import os
import readline
try:
 
    replay_filepath = os.environ.get('PYTHON_REPLAY_FILE')
    if replay_filepath and os.path.exists(replay_filepath):
        readline.parse_and_bind("tab: complete")
        class InteractiveReplayCompleter(object):
            def __init__(self, fo):
                self.buffer = [i[:-1] for i in fo.readlines()]
                self.curr_line = 0
                self.prev_completer = readline.get_completer()
                readline.set_completer(self.complete)
 
            def complete(self, text, state):
                if text:
                    if self.prev_completer is None:
                        return None
                    return self.prev_completer(text, state)
                if state > 0:
                    return None
                try:
                    next_line = '#'
                    while next_line.startswith('#'):
                        next_line = self.buffer[self.curr_line]
                        self.curr_line += 1
                    return next_line
                except:
                    return None
            def dump(self):
                for ind, line in enumerate(self.buffer):
                    print "%d: %s" % (ind, line)
                print "self.curr_line = %d" % self.curr_line
            def _get_sections(self):
                s_list = []
                s_dict = {}
                for ind, line in enumerate(self.buffer):
                    if line.startswith('#'):
                        section_name = line[1:].strip().lower()
                        s_dict[section_name] = ind
                        s_list.append((ind, section_name))
                return s_list, s_dict
            def list_sections(self):
                s_list, s_dict = self._get_sections()
                import sys
                sys.stderr.write("%s\n" % ("\n".join("%d: %s" % i for i in s_list)))
            def seek(self, arg):
                if isinstance(arg, int):
                    self.curr_line = arg
                else:
                    s_list, s_dict = self._get_sections()
                    self.curr_line = s_dict[arg.lower()]
        _c = InteractiveReplayCompleter(open(replay_filepath, 'rU'))
        del InteractiveReplayCompleter
    # the following code was taken from http://www.python.org/doc/tut/node15.html#interacting
    import atexit
 
    historyPath = os.path.expanduser("~/.pyhistory")
 
    def save_history(historyPath=historyPath):
        import readline
        readline.write_history_file(historyPath)
 
    if os.path.exists(historyPath):
        readline.read_history_file(historyPath)
 
    atexit.register(save_history)
 
    del atexit, historyPath, save_history
 
    del replay_filepath
finally:
    del os
    del readline