13257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel""" 23257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDanielatexit.py - allow programmer to define multiple exit functions to be executed 33257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDanielupon normal program termination. 43257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel 53257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDanielOne public function, register, is defined. 63257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel""" 73257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel 83257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel__all__ = ["register"] 93257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel 103257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDanielimport sys 113257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel 123257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel_exithandlers = [] 133257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDanieldef _run_exitfuncs(): 143257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel """run any registered exit functions 153257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel 163257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel _exithandlers is traversed in reverse order so functions are executed 173257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel last in, first out. 183257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel """ 193257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel 203257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel exc_info = None 213257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel while _exithandlers: 223257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel func, targs, kargs = _exithandlers.pop() 233257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel try: 243257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel func(*targs, **kargs) 253257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel except SystemExit: 263257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel exc_info = sys.exc_info() 273257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel except: 283257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel import traceback 293257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel print >> sys.stderr, "Error in atexit._run_exitfuncs:" 303257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel traceback.print_exc() 313257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel exc_info = sys.exc_info() 323257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel 333257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel if exc_info is not None: 343257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel raise exc_info[0], exc_info[1], exc_info[2] 353257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel 363257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel 373257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDanieldef register(func, *targs, **kargs): 383257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel """register a function to be executed upon normal program termination 393257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel 403257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel func - function to be called at exit 413257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel targs - optional arguments to pass to func 423257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel kargs - optional keyword arguments to pass to func 433257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel 443257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel func is returned to facilitate usage as a decorator. 453257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel """ 463257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel _exithandlers.append((func, targs, kargs)) 473257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel return func 483257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel 493257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDanielif hasattr(sys, "exitfunc"): 503257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel # Assume it's another registered exit function - append it to our list 513257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel register(sys.exitfunc) 523257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDanielsys.exitfunc = _run_exitfuncs 533257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel 543257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDanielif __name__ == "__main__": 553257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel def x1(): 563257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel print "running x1" 573257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel def x2(n): 583257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel print "running x2(%r)" % (n,) 593257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel def x3(n, kwd=None): 603257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel print "running x3(%r, kwd=%r)" % (n, kwd) 613257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel 623257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel register(x1) 633257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel register(x2, 12) 643257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel register(x3, 5, "bar") 653257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel register(x3, "no kwd args") 66