Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SIGINT and exception handling in Python

Tags:

python

signals

import signal
import sys
import time

def sigint_handler(signal, frame):
    print "signal"
    sys.exit(0)

signal.signal(signal.SIGINT, sigint_handler)

while 1:
    try:
        print "text"
        time.sleep(2)
    except KeyboardInterrupt:
        print "keybi"
        exit(0)
    except:
        print "except"
        continue

When I press Ctrl-C I see "signal" and "except" and the program doesn't exit.

  1. Why doesn't the program exit, while it apparently reaches sys.exit(0)?

  2. Why doesn't the program flow reach the KeyboardInterrupt section?

  3. What is the concise way to make Ctrl-C work and handle each except: case separately in different places without exiting?

like image 920
VladimirLenin Avatar asked Apr 09 '16 08:04

VladimirLenin


People also ask

What is SIGINT Python?

A Signal Handler is a user defined function, where Python signals can be handled. If we take the signal SIGINT (Interrupt Signal), the default behavior would be to stop the current running program. We can, however, assign a signal handler to detect this signal and do our custom processing instead!

What is exception handling in Python?

In Python, exceptions can be handled using a try statement. The critical operation which can raise an exception is placed inside the try clause. The code that handles the exceptions is written in the except clause. We can thus choose what operations to perform once we have caught the exception.

Why exception handling is needed in Python?

Exception handling allows you to separate error-handling code from normal code. An exception is a Python object which represents an error. As with code comments, exceptions helps you to remind yourself of what the program expects. It clarifies the code and enhances readability.

What is Sigterm in Python?

Python provides the Signal library allowing developers to catch Unix signals and set handlers for asynchronous events. For example, the 'SIGTERM' (Terminate) signal is received when issuing a 'kill' command for a given Unix process.


2 Answers

The program doesn't exit because sys.exit works by throwing a SystemExit exception, and your blanket except caught it.

The except KeyboardInterrupt doesn't fire because the SIGINT handler you installed overrides the default SIGINT handler, and the default SIGINT handler is responsible for raising a KeyboardInterrupt when you hit Ctrl-C.

As for your third question, it's unclear what you're asking.

like image 172
user2357112 supports Monica Avatar answered Oct 22 '22 10:10

user2357112 supports Monica


@user2357112 answered your first two questions, as to your third, you can create your own exception in the signal handler. In this example we raise MyError in the event of a SIGINT.

import signal
import time

class MyError(Exception): 
    pass

def handler(sig, frame):
    raise MyError('Received signal ' + str(sig) +
                  ' on line ' + str(frame.f_lineno) +
                  ' in ' + frame.f_code.co_filename)    

signal.signal(signal.SIGINT, handler)

try:
    while 1:
        time.sleep(1)        # Hit <CTRL>+C here
except KeyboardInterrupt:
    print('Keyboard interrupt caught')
except MyError as err:
    print("Hiccup:",err)
    # do stuff

print('Clean exit')

If you comment out the call to signal.signal() then you will get a KeyboardInterrupt, as described.

like image 28
cdarke Avatar answered Oct 22 '22 11:10

cdarke