9

Is there a way to programmatically interrupt Python's raw_input? Specifically, I would like to present a prompt to the user, but also listen on a socket descriptor (using select, for instance) and interrupt the prompt, output something, and redisplay the prompt if data comes in on the socket.

The reason for using raw_input rather than simply doing select on sys.stdin is that I would like to use the readline module to provide line editing functionality for the prompt.

Ray
  • 1,769
  • 1
  • 17
  • 22

1 Answers1

2

As far as I know... "Sort of".

raw_input is blocking so the only way I can think of is spawning a subprocess/thread to retrieve the input, and then simply communicate with the thread/subprocess. It's a pretty dirty hack (at least it seems that way to me), but it should work cross platform. The other alternative, of course, is to use either the curses module on linux or get this one for windows.

Wayne Werner
  • 49,299
  • 29
  • 200
  • 290
  • 1
    I'm facing right now the same problem. I thought of the first solution (calling raw_input() in another thread), however after searching I found out there's still no way to interrupt it, cause even after raising an exception from one thread in different one (http://stackoverflow.com/questions/323972/is-there-any-way-to-kill-a-thread-in-python) it won't die, when it's busy with system call (and raw_input() classifies as one, doesn't it?)... :( – Sushi271 Mar 16 '15 at 00:44
  • I face exactly the same issue. How exactly would you solve this problem using a separate thread for the raw_input? It would still be blocking. – Tobias Nov 29 '18 at 16:57
  • @Tobias hence, "Sort of". Experimenting a bit more, it pretty much seems that this is just a bad idea all around, i.e. you're just reimplementing curses. If you're using multiprocessing or Popen you should be able to signal the other process/thread, but all of that is just a lot of overhead for what you get for free via another approach. – Wayne Werner Dec 04 '18 at 14:59
  • Thanks for the answer. I am somewhat surprised this is such a difficult problem. After many tries I solved my problem by overwriting the prompt and reprinting the content after printing OUTPUT: current_buffer = readline.get_line_buffer() // print(term.clear_eol+term.move_x(0)+OUTPUT) // print('> '+current_buffer, end='') – Tobias Dec 05 '18 at 12:35