Programmatically exit the REPL

Matthew Fitzgibbons elessar at
Tue Aug 26 22:47:45 CEST 2008

Matthew Fitzgibbons wrote:
> I've got a pretty complex interactive command line program. Instead of 
> writing my own REPL, I'm using the Python interpreter (an infinitely 
> better solution). This program has two threads, a background thread and 
> the REPL thread. When you call quit() or sys.exit() in the REPL thread, 
> everything is perfectly happy. However, the background thread does some 
> long-running jobs, and I want it to have the ability to exit the program 
> when the job is complete. When I call quit() or sys.exit() from the 
> background thread, the REPL merrily continues on its way.
> This is a very frustrating problem, so I'm hoping someone can shed some 
> light on it. Am I missing something simple? Or is this just impossible? 
> I don't see anything about breaking out of interact() in the code module 
> docs.
> Here's a minimal example:
> #!/usr/bin/env python -i
> # You get the same behavior using code.interact()
> import sys
> import time
> import threading
> def end_the_program():
>     # works if you call it from the REPL thread,
>     # but not the background thread
>     print "called end_the_program()"
>     sys.exit()
>     # quit() # using quit() rather than sys.exit()
>              # results in identical behavior
> keep_going = True
> def runner():
>     while keep_going:
>         time.sleep(0.1)
>     end_the_program()
> threading.Thread(target=runner).start()
> # end example
> Here's the console session (edited for clarity):
> Desktop$ ./
>  >>> keep_going = False
> called end_the_program()
> # notice we didn't exit here
>  >>> end_the_program()
> called end_the_program()
> # but we did exit here
> Desktop$
> -Matt

Here's a modified example that _almost_ works:

#!/usr/bin/env python

import code
import time
import threading

keep_going = True
def runner():
     while keep_going:
     ic.push("quit()") # this will exit the InteractiveConsole loop!

ic = code.InteractiveConsole(locals())

# end example

It uses code.InteractiveConsole instead of python -i. When you push 
"quit()" to the InteractiveConsole, the loop exits, but the raw_input 
call is still blocking. Argh!

Console session:

Desktop$ ./ && echo done
 >>> keep_going = False
 >>> <hit enter one more time...>

Does anyone know how to make raw_input think it has gotten input?


More information about the Python-list mailing list