How to capture SIGINT in Python?

Out of all the various signals available to us in Python, SIGINT is probably the most commonly used. But what exactly does it do? When a program is in the process of executing itself, we can trigger SIGINT by pressing CTRL + C to stop the programs execution prematurely.

Sometimes we may wish to change this behavior, so in this tutorial we will be discussing how to “handle” or “capture” this event.


Handling the SIGINT event in Python

Try running the following piece of code on your device. We are using the sleep() function from the time module, to put our program to sleep for 5 seconds. Due to the nature of SIGINT however (as signals are asynchronous), we can use it to terminate the program before the 5 seconds are complete. Try doing so, before we change its default behavior.

import time 

print("Waiting for 5 seconds...")
time.sleep(5)

So if you did it correctly, pressing CTRL + C will trigger SIGINT which terminates the execution. This is the default behaviour.

Now lets try to “capture” SIGINT, and change its behavior. Instead of terminating the program, it will simply print out its Signal ID instead.

import signal  
import time 

# Our signal handler
def signal_handler(signum, frame):  
    print("Signal ID:", signum)  
 
# Handling SIGINT 
signal.signal(signal.SIGINT, signal_handler)

print("Waiting for 5 seconds...")
time.sleep(5)

Try running the above code. You will notice that CTRL + C (SIGINT) will not terminate the program anymore, instead it will print out a line onto the console.


Using Default Behavior for SIGINT

We don’t have to pick however, between custom behavior and the default behavior for SIGINT. We can just do both!

This is achieved by storing the original handler for SIGINT, and calling it within our custom signal_handler function when we are done with our custom code. This could be useful in a scenario, where you want to “gracefully” handle the shutdown of your program via the CTRL + C command.

Whenever you call signal.signal(params), the original function is returned. Alternatively, we can use the getsignal() function as well, as shown below (commented out).

import signal  
import time 

# Our signal handler
def signal_handler(signum, frame):  
    global original_handler
    print("Signal ID:", signum)  
    original_handler(signum, frame)
 
# Handling SIGINT 
# original_handler = signal.getsignal(signal.SIGINT)
original_handler = signal.signal(signal.SIGINT, signal_handler)

print("Waiting for 5 seconds...")
time.sleep(5)

To put it simply, the above code will print out a statement, and then raise a KeyboardInterrupt.


This marks the end of the How to capture SIGINT in Python Tutorial. Any suggestions or contributions for CodersLegacy are more than welcome. Questions regarding the tutorial content can be asked in the comments section below.