Commit | Line | Data |
---|---|---|
920dae64 AT |
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 | _exithandlers.append((func, targs, kargs)) | |
45 | ||
46 | if hasattr(sys, "exitfunc"): | |
47 | # Assume it's another registered exit function - append it to our list | |
48 | register(sys.exitfunc) | |
49 | sys.exitfunc = _run_exitfuncs | |
50 | ||
51 | if __name__ == "__main__": | |
52 | def x1(): | |
53 | print "running x1" | |
54 | def x2(n): | |
55 | print "running x2(%r)" % (n,) | |
56 | def x3(n, kwd=None): | |
57 | print "running x3(%r, kwd=%r)" % (n, kwd) | |
58 | ||
59 | register(x1) | |
60 | register(x2, 12) | |
61 | register(x3, 5, "bar") | |
62 | register(x3, "no kwd args") |