Skip to content

Commit 80f9604

Browse files
[3.14] Reword atexit docs (GH-156086) (GH-156879)
For the `atexit` module: - Move common info from `register` to the module level (a lot of this was duplicated -- less maintainable and harder to read) - Use *interpreter shutdown* consistently, introducing it as a more general term for the old docs' *program termination*. - Use the term *exit handler* consistently - Move warning for a mitigated footgun to a change entry - Add a new warning about keeping things usable Similarly clarify docs for the `atexit` attribute in `weakref`. (cherry picked from commit 1d28836) Co-authored-by: Petr Viktorin <encukou@gmail.com>
1 parent e68849f commit 80f9604

2 files changed

Lines changed: 54 additions & 43 deletions

File tree

Doc/library/atexit.rst

Lines changed: 47 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -9,59 +9,69 @@
99

1010
--------------
1111

12-
The :mod:`!atexit` module defines functions to register and unregister cleanup
13-
functions. Functions thus registered are automatically executed upon normal
14-
interpreter termination. :mod:`!atexit` runs these functions in the *reverse*
15-
order in which they were registered; if you register ``A``, ``B``, and ``C``,
16-
at interpreter termination time they will be run in the order ``C``, ``B``,
17-
``A``.
18-
19-
**Note:** The functions registered via this module are not called when the
12+
The :mod:`!atexit` module defines functions to register and unregister
13+
:dfn:`exit handlers`: functions that are automatically executed
14+
"at exit", that is, upon normal program termination (for instance,
15+
if :func:`sys.exit` is called or the main module's execution completes)
16+
or, more generally, upon :term:`interpreter shutdown`.
17+
18+
At exit, all registered exit handlers are called
19+
in the *reverse* order in which they were registered.
20+
If you register ``A``, ``B``, and ``C``, at interpreter shutdown time they
21+
will be run in the order ``C``, ``B``, ``A``.
22+
The assumption is that lower level modules will normally be imported before
23+
higher level modules and thus must be cleaned up later.
24+
25+
If an exception is raised during execution of an exit handler, a traceback is
26+
printed (unless :exc:`SystemExit` is raised) and the exception information is
27+
saved. After all exit handlers have had a chance to run, the last exception to
28+
be raised is re-raised.
29+
30+
In programs that use multiple interpreters, each interpreter has its own stack
31+
of exit handlers, which are executed when the interpreter shuts down
32+
(for example, with :meth:`concurrent.interpreters.Interpreter.close` or the
33+
C API :c:func:`Py_EndInterpreter`).
34+
Registration functions in this module only affect the interpreter they are
35+
called from.
36+
37+
**Note:** Exit handlers are not called when the
2038
program is killed by a signal not handled by Python, when a Python fatal
2139
internal error is detected, or when :func:`os._exit` is called.
2240

2341
**Note:** The effect of registering or unregistering functions from within
2442
a cleanup function is undefined.
2543

26-
.. versionchanged:: 3.7
27-
When used with C-API subinterpreters, registered functions
28-
are local to the interpreter they were registered in.
44+
.. warning::
45+
When writing exit handlers, especially in C API extensions, keep in mind
46+
that other exit handlers may still run arbitrary Python code after you
47+
clean up.
48+
Such code should succeed or fail with an exception, rather than crash.
2949

30-
.. function:: register(func, *args, **kwargs)
50+
.. versionchanged:: 3.12
51+
Attempts to start a new thread or :func:`os.fork` a new process
52+
in an exit handler now leads to :exc:`RuntimeError`.
53+
Previously, this could cause race conditions between the main Python
54+
runtime thread freeing thread states while internal :mod:`threading`
55+
routines or the new process try to use that state, which could lead to
56+
crashes rather than clean shutdown.
3157

32-
Register *func* as a function to be executed at termination. Any optional
33-
arguments that are to be passed to *func* must be passed as arguments to
34-
:func:`register`. It is possible to register the same function and arguments
35-
more than once.
58+
.. versionchanged:: 3.7
59+
When used with subinterpreters, registered functions
60+
are local to the interpreter they were registered in.
3661

37-
At normal program termination (for instance, if :func:`sys.exit` is called or
38-
the main module's execution completes), all functions registered are called in
39-
last in, first out order. The assumption is that lower level modules will
40-
normally be imported before higher level modules and thus must be cleaned up
41-
later.
62+
.. function:: register(func, *args, **kwargs)
4263

43-
If an exception is raised during execution of the exit handlers, a traceback is
44-
printed (unless :exc:`SystemExit` is raised) and the exception information is
45-
saved. After all exit handlers have had a chance to run, the last exception to
46-
be raised is re-raised.
64+
Register *func* as an exit handler.
65+
Any optional arguments that are to be passed to *func* must be passed as
66+
arguments to :func:`register`.
67+
It is possible to register the same function and arguments more than once.
4768

4869
This function returns *func*, which makes it possible to use it as a
4970
decorator.
5071

51-
.. warning::
52-
Starting new threads or calling :func:`os.fork` from a registered
53-
function can lead to race condition between the main Python
54-
runtime thread freeing thread states while internal :mod:`threading`
55-
routines or the new process try to use that state. This can lead to
56-
crashes rather than clean shutdown.
57-
58-
.. versionchanged:: 3.12
59-
Attempts to start a new thread or :func:`os.fork` a new process
60-
in a registered function now leads to :exc:`RuntimeError`.
61-
6272
.. function:: unregister(func)
6373

64-
Remove *func* from the list of functions to be run at interpreter shutdown.
74+
Remove *func* from the list of exit handlers.
6575
:func:`unregister` silently does nothing if *func* was not previously
6676
registered. If *func* has been registered more than once, every occurrence
6777
of that function in the :mod:`!atexit` call stack will be removed. Equality

Doc/library/weakref.rst

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -286,9 +286,10 @@ same issues as the :meth:`WeakKeyDictionary.keyrefs` method.
286286
from an object's :meth:`~object.__del__` method or a weak reference's
287287
callback.
288288

289-
When the program exits, each remaining live finalizer is called
290-
unless its :attr:`atexit` attribute has been set to false. They
291-
are called in reverse order of creation.
289+
When the program exits (or more generally, at :term:`interpreter shutdown`),
290+
each remaining live finalizer is called unless its :attr:`atexit` attribute
291+
has been set to false.
292+
They are called in reverse order of creation.
292293

293294
A finalizer will never invoke its callback during the later part of
294295
the :term:`interpreter shutdown` when module globals are liable to have
@@ -317,9 +318,9 @@ same issues as the :meth:`WeakKeyDictionary.keyrefs` method.
317318

318319
.. attribute:: atexit
319320

320-
A writable boolean property which by default is true. When the
321-
program exits, it calls all remaining live finalizers for which
322-
:attr:`.atexit` is true. They are called in reverse order of
321+
A writable boolean property which by default is true. At
322+
:term:`interpreter shutdown`, all remaining live finalizers for which
323+
:attr:`.atexit` is true are called in reverse order of
323324
creation.
324325

325326
.. note::

0 commit comments

Comments
 (0)