Utilities for interfacing with the standard library’s atexit module.¶
- class sage.cpython.atexit.restore_atexit¶
Bases:
object
Context manager that restores the state of the atexit module to its previous state when exiting the context.
INPUT:
run
(bool, default: False) – if True, when exiting the context (but before restoring the old exit functions), run all atexit functions which were added inside the context.clear
(bool, default: equal torun
) – if True, clear already registered atexit handlers upon entering the context.
Warning
The combination
run=True
andclear=False
will cause already-registered exit functions to be run twice: once when exiting the context and again when exiting Python.EXAMPLES:
For this example we will wrap the entire example with
restore_atexit(clear=True)
so as to start with a fresh atexit module state for the sake of the example.Note that the function
atexit._run_exitfuncs()
runs all registered handlers, and then clears the list of handlers, so we can use it to test manipulation of theatexit
state:sage: import atexit sage: from sage.cpython.atexit import restore_atexit sage: def handler(*args, **kwargs): ....: import sys # see https://trac.sagemath.org/ticket/25270#comment:56 ....: sys.stdout.write(str((args, kwargs))) ....: sys.stdout.write('\n') sage: atexit.register(handler, 1, 2, c=3) <function handler at 0x...> sage: atexit.register(handler, 4, 5, d=6) <function handler at 0x...> sage: with restore_atexit(clear=True): ....: atexit._run_exitfuncs() # Should be none registered ....: atexit.register(handler, 1, 2, c=3) ....: with restore_atexit(): ....: atexit._run_exitfuncs() # Run just registered handler ....: atexit._run_exitfuncs() # Handler should be run again <function handler at 0x...> ((1, 2), {'c': 3}) ((1, 2), {'c': 3})
We test the
run
option:sage: with restore_atexit(run=True): ....: # this handler is run when exiting the context ....: _ = atexit.register(handler, 7, 8, e=9) ((7, 8), {'e': 9}) sage: with restore_atexit(clear=False, run=True): ....: # original handlers are run when exiting the context ....: pass ((4, 5), {'d': 6}) ((1, 2), {'c': 3})
The original handlers are still in place:
sage: atexit._run_exitfuncs() ((4, 5), {'d': 6}) ((1, 2), {'c': 3})