I recently started with python . I was playing with handling the keyboard interrupt , when I came across this behavior
import signal,sys
def handleInt(sign,no):
print "interrupted"
signal.signal(signal.SIGINT,handleInt) # exception raised is IOError
try:
sys.stdin.read(1)
except IOError:
print "io interrupt"
but if I change the signal handling to after the try-except
import signal,sys
def handleInt(sign,no):
print "interrupted"
try:
sys.stdin.read(1)
except KeyboardInterrupt:
print "keyboard interrupt"
signal.signal(signal.SIGINT,handleInt) # exception raised is KeyboardInterrupt
When I press ctrl+c , there is a difference in the exception in the two cases .So why is this behavior ?
Python has its own built-in singal handler for SIGINT
. This handler simply raises KeyboardInterrupt
. In your first code, you replaced the built-in handler with the new handler hence you see this output:
$python test_exc.py
^Cinterrupted
Note that io interrupted
is not printed, since no exception was raised. In fact modifying the code to:
import signal,sys
def handleInt(sign,no):
print "interrupted"
signal.signal(signal.SIGINT, handleInt) # exception raised is IOError
try:
sys.stdin.read(1)
except IOError:
print "io interrupt"
else:
# else is executed only if no exception was raised
print "done"
You get:
$python test_exc.py
^Cinterrupted
done
Note that hitting Ctrl+C
does not block the call to sys.stdin.read(1)
hence you still have to press some key to let the program continue. Raising an exception inside the signal handler will raise it as if the call to sys.stdin.read(1)
produced it:
import signal,sys
def handleInt(sign,no):
print "interrupted"
raise OSError
signal.signal(signal.SIGINT, handleInt) # exception raised is IOError
try:
sys.stdin.read(1)
except IOError:
print "io interrupt"
else:
# else is executed only if no exception was raised
print "done"
Sample run:
$python test_exc.py
^Cinterrupted
Traceback (most recent call last):
File "test_exc.py", line 10, in <module>
sys.stdin.read(1)
File "test_exc.py", line 5, in handleInt
raise OSError
OSError
Note: you can access the default signal handler via signal.default_int_handler
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With