This happens if a prompt is written using sys.stdout.write or print instead of raw_input. The following script demonstrates it:
$ cat overwrite.py
import readline, sys
if 'libedit' in readline.__doc__:
readline.parse_and_bind('bind ^I rl_complete')
else:
readline.parse_and_bind('tab: complete')
def set_completer(choices):
choices = sorted(map(str,choices))
def completer(txt, state):
if state == 0:
completer.options = [c for c in choices if c.startswith(txt)]
if state < len(completer.options):
return completer.options[state]
return None
readline.set_completer(completer)
set_completer(['foo','flup'])
sys.stdout.write('input: ')
x = raw_input()
print x
If you run python overwrite.py, you get the expected prompt: “input: “. If you hit backspace once, nothing gets deleted (readline thinks it’s already at the beginning of the line, I guess). If you hit ‘f’ then backspace, however, the whole line, prompt included, is wiped.
It would be very inconvenient to have to go through and replace all the places I write to stdout and am expecting to get input from the user with calls to raw_input, so I hope it’s not necessary to use raw_input. The python docs are uncharacteristically sparse concerning readline.
There is no other real way to fix this; while readline has the
rl_already_promptedvariable, it still requires the prompt to be passed in so that readline’s functions can manage the input line properly.