2

I'm trying to setup a pre populated input in my python script. Essentially what I'm trying to do is create an input that if called will be pre-populated with a variable set earlier in the script (usernames and IP addresses). I've found the following post (Is it possible to prefill a input() in Python 3's Command Line Interface?) with a suggestion but for some reason when I run it nothing happens.

import readline

def input_with_prefill(prompt, text):
    def hook():
        readline.insert_text(text)
        readline.redisplay()
    readline.set_pre_input_hook(hook)
    result = input(prompt)
    readline.set_pre_input_hook()
    return result

Anything I pass to the prompt variable works but nothing seems to happen with the text variable the input remains blank. If I run the script in the terminal then I can see the text variable but its placed before the prompt and is uneditable which defeats the purpose of what I'm trying to do. Which is allow the user to edit the username or IP they've entered if login fails.

I'm using Python 3.8 on Manjaro Linux. Any help would be much appreciated.

snakecharmerb
  • 47,570
  • 11
  • 100
  • 153
rohtua
  • 165
  • 1
  • 11
  • your code works on my NixOS in Python 3.8 interactive interpreter shell. Maybe you need to check if you're not running an alternative to readline, like libedit? https://docs.python.org/3/library/readline.html – Mika Feiler Nov 15 '19 at 17:05
  • @MichałKrzysztofFeiler Hi thanks for the response I don't have libedit just tried it and module can't be found. I'm definitely using readline but for some reason I'm only seeing the prompt variable when running it (at least from the IDE). I've tried it again from the terminal shell and it seems to have worked that way and running in the terminal as a script (there must be something with one of the variables with my main script that stopped that one working in the terminal. I've tried the basic Python IDLE and Spyder and neither of them show the prefilled input when running through the IDLE? – rohtua Nov 15 '19 at 17:39
  • 1
    This approach cannot possibly work with IDLE - it's using a GUI widget to accept user input, `readline` plays no part in the process. The same thing is likely to apply to *any* GUI-based IDE. – jasonharper Nov 15 '19 at 18:06

2 Answers2

0

Here you go. This uses a nested function that 'remembers' the context from the outer function:

def my_input_function(preload_lines):  # array of lines to return
    def my_input(prompt=''):
        nonlocal preload_lines
        if preload_lines:
            line = preload_lines[0]
            preload_lines = preload_lines[1:]
            return line
        else:
            return input(prompt)
    return my_input

input_ = my_input_function(['Line 1', 'Line 2'])
print(input_("Next?"))
print(input_("Next?"))
print(input_("Next?"))
print(input_("Next?"))

Running it:

Line 1
Line 2
Next?line3
line3
Next?line4
line4
Charles Merriam
  • 19,908
  • 6
  • 73
  • 83
0

As @jasonharper said:

This approach cannot possibly work with IDLE - it's using a GUI widget to accept user input, readline plays no part in the process. The same thing is likely to apply to any GUI-based IDE.

I recommend making your IDE start a regular terminal emulator and redirect all input and output to/from the program from/to it, as your production environment will, I guess, involve a regular terminal emulator anyway.

Mika Feiler
  • 474
  • 3
  • 17