diff --git a/Doc/library/atexit.rst b/Doc/library/atexit.rst index b5caf5502d0e1c..417611307577fd 100644 --- a/Doc/library/atexit.rst +++ b/Doc/library/atexit.rst @@ -6,59 +6,69 @@ -------------- -The :mod:`!atexit` module defines functions to register and unregister cleanup -functions. Functions thus registered are automatically executed upon normal -interpreter termination. :mod:`!atexit` runs these functions in the *reverse* -order in which they were registered; if you register ``A``, ``B``, and ``C``, -at interpreter termination time they will be run in the order ``C``, ``B``, -``A``. - -**Note:** The functions registered via this module are not called when the +The :mod:`!atexit` module defines functions to register and unregister +:dfn:`exit handlers`: functions that are automatically executed +"at exit", that is, upon normal program termination (for instance, +if :func:`sys.exit` is called or the main module's execution completes) +or, more generally, upon :term:`interpreter shutdown`. + +At exit, all registered exit handlers are called +in the *reverse* order in which they were registered. +If you register ``A``, ``B``, and ``C``, at interpreter shutdown time they +will be run in the order ``C``, ``B``, ``A``. +The assumption is that lower level modules will normally be imported before +higher level modules and thus must be cleaned up later. + +If an exception is raised during execution of an exit handler, a traceback is +printed (unless :exc:`SystemExit` is raised) and the exception information is +saved. After all exit handlers have had a chance to run, the last exception to +be raised is re-raised. + +In programs that use multiple interpreters, each interpreter has its own stack +of exit handlers, which are executed when the interpreter shuts down +(for example, with :meth:`concurrent.interpreters.Interpreter.close` or the +C API :c:func:`Py_EndInterpreter`). +Registration functions in this module only affect the interpreter they are +called from. + +**Note:** Exit handlers are not called when the program is killed by a signal not handled by Python, when a Python fatal internal error is detected, or when :func:`os._exit` is called. **Note:** The effect of registering or unregistering functions from within a cleanup function is undefined. -.. versionchanged:: 3.7 - When used with C-API subinterpreters, registered functions - are local to the interpreter they were registered in. +.. warning:: + When writing exit handlers, especially in C API extensions, keep in mind + that other exit handlers may still run arbitrary Python code after you + clean up. + Such code should succeed or fail with an exception, rather than crash. -.. function:: register(func, *args, **kwargs) +.. versionchanged:: 3.12 + Attempts to start a new thread or :func:`os.fork` a new process + in an exit handler now leads to :exc:`RuntimeError`. + Previously, this could cause race conditions between the main Python + runtime thread freeing thread states while internal :mod:`threading` + routines or the new process try to use that state, which could lead to + crashes rather than clean shutdown. - Register *func* as a function to be executed at termination. Any optional - arguments that are to be passed to *func* must be passed as arguments to - :func:`register`. It is possible to register the same function and arguments - more than once. +.. versionchanged:: 3.7 + When used with subinterpreters, registered functions + are local to the interpreter they were registered in. - At normal program termination (for instance, if :func:`sys.exit` is called or - the main module's execution completes), all functions registered are called in - last in, first out order. The assumption is that lower level modules will - normally be imported before higher level modules and thus must be cleaned up - later. +.. function:: register(func, *args, **kwargs) - If an exception is raised during execution of the exit handlers, a traceback is - printed (unless :exc:`SystemExit` is raised) and the exception information is - saved. After all exit handlers have had a chance to run, the last exception to - be raised is re-raised. + Register *func* as an exit handler. + Any optional arguments that are to be passed to *func* must be passed as + arguments to :func:`register`. + It is possible to register the same function and arguments more than once. This function returns *func*, which makes it possible to use it as a decorator. - .. warning:: - Starting new threads or calling :func:`os.fork` from a registered - function can lead to race condition between the main Python - runtime thread freeing thread states while internal :mod:`threading` - routines or the new process try to use that state. This can lead to - crashes rather than clean shutdown. - - .. versionchanged:: 3.12 - Attempts to start a new thread or :func:`os.fork` a new process - in a registered function now leads to :exc:`RuntimeError`. - .. function:: unregister(func) - Remove *func* from the list of functions to be run at interpreter shutdown. + Remove *func* from the list of exit handlers. :func:`unregister` silently does nothing if *func* was not previously registered. If *func* has been registered more than once, every occurrence of that function in the :mod:`!atexit` call stack will be removed. Equality diff --git a/Doc/library/weakref.rst b/Doc/library/weakref.rst index 7cc0c33fda353c..52fedb00a940c9 100644 --- a/Doc/library/weakref.rst +++ b/Doc/library/weakref.rst @@ -290,9 +290,10 @@ same issues as the :meth:`WeakKeyDictionary.keyrefs` method. from an object's :meth:`~object.__del__` method or a weak reference's callback. - When the program exits, each remaining live finalizer is called - unless its :attr:`atexit` attribute has been set to false. They - are called in reverse order of creation. + When the program exits (or more generally, at :term:`interpreter shutdown`), + each remaining live finalizer is called unless its :attr:`atexit` attribute + has been set to false. + They are called in reverse order of creation. A finalizer will never invoke its callback during the later part of the :term:`interpreter shutdown` when module globals are liable to have @@ -321,9 +322,9 @@ same issues as the :meth:`WeakKeyDictionary.keyrefs` method. .. attribute:: atexit - A writable boolean property which by default is true. When the - program exits, it calls all remaining live finalizers for which - :attr:`.atexit` is true. They are called in reverse order of + A writable boolean property which by default is true. At + :term:`interpreter shutdown`, all remaining live finalizers for which + :attr:`.atexit` is true are called in reverse order of creation. .. note::