shutdown
sends the SIGTERM
signal, which atexit
does not handle. Nor will context managers, finally
blocks, etc.
import signal
signal.getsignal(signal.SIGTERM)
Out[64]: 0 #i.e. nothing
Contrast this with, say ctrl-C:
signal.getsignal(signal.SIGINT)
Out[65]: <function signal.default_int_handler> #i.e. something
You can register your byebye
function with signal
to run instead of doing nothing (which leads to the interpreter eventually getting killed by the shell)
signal.signal(signal.SIGTERM,byebye)
If you do the above you'll need to do two things:
- change the signature of
byebye
to accept the two arguments thatsignal
will pass to it. - you should do something like call
sys.exit()
at the end of yourbyebye
function to allow python to gracefully close up shop.
You could alternatively do some combination of signal
and atexit
:
import sys
signal.signal(signal.SIGTERM, lambda num, frame: sys.exit(0))
Which would drop right in to your current code. This ensures the atomicity of your cleanup operation (i.e. byebye
is guaranteed to be the last I/O operation) at the cost of being a bit clunky.