atexit.py 1.7 KB

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