Programmatically exit the REPL

Matthew Fitzgibbons elessar at nienna.org
Tue Aug 26 03:07:52 CEST 2008


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$ ./exit_repl.py
 >>> 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



More information about the Python-list mailing list