I want to know if a Python script is terminating correctly or not. For this I am using atexit
but the problem is that I do not know how to differentiate if atexit was called with sys.exit(0) or non zero or an exception.
Reasoning: if program ends properly, it will do nothing but if the program ends by an exception or returning an error code (exit status) different than zero I want to trigger some action.
In case you will wonder why I'm not using try/finally is because I want to add the same behaviour for a dozen of scripts that are importing a common module. Instead of modifying all of them, I want to add the atexit() hack to the module being imported and get this behaviour for free in all of them.
You can solve this using sys.excepthook
and by monkey-patching sys.exit()
:
import atexit
import sys
class ExitHooks(object):
def __init__(self):
self.exit_code = None
self.exception = None
def hook(self):
self._orig_exit = sys.exit
sys.exit = self.exit
sys.excepthook = self.exc_handler
def exit(self, code=0):
self.exit_code = code
self._orig_exit(code)
def exc_handler(self, exc_type, exc, *args):
self.exception = exc
hooks = ExitHooks()
hooks.hook()
def foo():
if hooks.exit_code is not None:
print("death by sys.exit(%d)" % hooks.exit_code)
elif hooks.exception is not None:
print("death by exception: %s" % hooks.exception)
else:
print("natural death")
atexit.register(foo)
# test
sys.exit(1)