Home | History | Annotate | Download | only in Lib
      1 """
      2 atexit.py - allow programmer to define multiple exit functions to be executed
      3 upon normal program termination.
      4 
      5 One public function, register, is defined.
      6 """
      7 
      8 __all__ = ["register"]
      9 
     10 import sys
     11 
     12 _exithandlers = []
     13 def _run_exitfuncs():
     14     """run any registered exit functions
     15 
     16     _exithandlers is traversed in reverse order so functions are executed
     17     last in, first out.
     18     """
     19 
     20     exc_info = None
     21     while _exithandlers:
     22         func, targs, kargs = _exithandlers.pop()
     23         try:
     24             func(*targs, **kargs)
     25         except SystemExit:
     26             exc_info = sys.exc_info()
     27         except:
     28             import traceback
     29             print >> sys.stderr, "Error in atexit._run_exitfuncs:"
     30             traceback.print_exc()
     31             exc_info = sys.exc_info()
     32 
     33     if exc_info is not None:
     34         raise exc_info[0], exc_info[1], exc_info[2]
     35 
     36 
     37 def register(func, *targs, **kargs):
     38     """register a function to be executed upon normal program termination
     39 
     40     func - function to be called at exit
     41     targs - optional arguments to pass to func
     42     kargs - optional keyword arguments to pass to func
     43 
     44     func is returned to facilitate usage as a decorator.
     45     """
     46     _exithandlers.append((func, targs, kargs))
     47     return func
     48 
     49 if hasattr(sys, "exitfunc"):
     50     # Assume it's another registered exit function - append it to our list
     51     register(sys.exitfunc)
     52 sys.exitfunc = _run_exitfuncs
     53 
     54 if __name__ == "__main__":
     55     def x1():
     56         print "running x1"
     57     def x2(n):
     58         print "running x2(%r)" % (n,)
     59     def x3(n, kwd=None):
     60         print "running x3(%r, kwd=%r)" % (n, kwd)
     61 
     62     register(x1)
     63     register(x2, 12)
     64     register(x3, 5, "bar")
     65     register(x3, "no kwd args")
     66