Handling signals in Python inside a function I have code that needs to exit gracefully. To simplify things, I am presenting an example based on the answer given here.

Since I need to handle a few signals, I thought of putting this logic in a function:

def set_signals():
   original_sigint = signal.getsignal(signal.SIGINT)
   signal.signal(signal.SIGINT, exit_gracefully)
   signal.signal(signal.SIGTERM, exit_gracefully)
   signal.signal(signal.SIGINT, exit_gracefully)
   signal.signal(signal.SIGALRM, exit_gracefully)
   signal.signal(signal.SIGHUP, signal.SIG_IGN)


Thus, the main block of the python code should be:

if __name__ == '__main__':
    # store the original SIGINT handler
    set_signals()
    run_program()


This will fail however, since the exit_gracefully does not know the variable original_init. 

Therefore, my solution was to create original_sigint as a global variable. 

import signal
import time
import sys


original_sigint = None


def run_program():
    while True:
        time.sleep(1)
        print("a")


def exit_gracefully(signum, frame):
    # restore the original signal handler as otherwise evil things will happen
    # in raw_input when CTRL+C is pressed, and our signal handler is not re-entrant
    global original_sigint
    signal.signal(signal.SIGINT, original_sigint)

    try:
        if raw_input("\nReally quit? (y/n)&gt; ").lower().startswith('y'):
            sys.exit(1)

    except KeyboardInterrupt:
        print("Ok ok, quitting")
        sys.exit(1)

    # restore the exit gracefully handler here
    signal.signal(signal.SIGINT, exit_gracefully)


def set_signals():
    global original_sigint
    original_sigint = signal.getsignal(signal.SIGINT)
    signal.signal(signal.SIGINT, exit_gracefully)
    signal.signal(signal.SIGTERM, exit_gracefully)
    signal.signal(signal.SIGINT, exit_gracefully)
    signal.signal(signal.SIGALRM, exit_gracefully)
    signal.signal(signal.SIGHUP, signal.SIG_IGN)


if __name__ == '__main__':
    # store the original SIGINT handler
    set_signals()
    run_program()


This approach works, but I am not happy with the use of another global variable (the code I working on is quite and is already littered with those). So the question is, how would you do it differently?
What about implementing your signal handling code inside a class? This could look something like the following:

class GracefulExit:
    def __enter__(self):
        # set up signals here
        # store old signal handlers as instance variables

    def __exit__(self, type, value, traceback):
        # restore old signal handlers


You can then use this in your code as follows:

with GracefulExit():
    # Signals will be caught inside this block.

# Signals will no more be caught here.


You'll find more examples of how to use the with-statement on the web.