Skip to content

Commit 1a7816f

Browse files
encukoumiss-islington
authored andcommitted
Reword atexit docs (GH-156086)
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 6409b1e commit 1a7816f

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
@@ -6,59 +6,69 @@
66

77
--------------
88

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

2038
**Note:** The effect of registering or unregistering functions from within
2139
a cleanup function is undefined.
2240

23-
.. versionchanged:: 3.7
24-
When used with C-API subinterpreters, registered functions
25-
are local to the interpreter they were registered in.
41+
.. warning::
42+
When writing exit handlers, especially in C API extensions, keep in mind
43+
that other exit handlers may still run arbitrary Python code after you
44+
clean up.
45+
Such code should succeed or fail with an exception, rather than crash.
2646

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

29-
Register *func* as a function to be executed at termination. Any optional
30-
arguments that are to be passed to *func* must be passed as arguments to
31-
:func:`register`. It is possible to register the same function and arguments
32-
more than once.
55+
.. versionchanged:: 3.7
56+
When used with subinterpreters, registered functions
57+
are local to the interpreter they were registered in.
3358

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

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

4566
This function returns *func*, which makes it possible to use it as a
4667
decorator.
4768

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

61-
Remove *func* from the list of functions to be run at interpreter shutdown.
71+
Remove *func* from the list of exit handlers.
6272
:func:`unregister` silently does nothing if *func* was not previously
6373
registered. If *func* has been registered more than once, every occurrence
6474
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
@@ -281,9 +281,10 @@ same issues as the :meth:`WeakKeyDictionary.keyrefs` method.
281281
from an object's :meth:`~object.__del__` method or a weak reference's
282282
callback.
283283

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

288289
A finalizer will never invoke its callback during the later part of
289290
the :term:`interpreter shutdown` when module globals are liable to have
@@ -312,9 +313,9 @@ same issues as the :meth:`WeakKeyDictionary.keyrefs` method.
312313

313314
.. attribute:: atexit
314315

315-
A writable boolean property which by default is true. When the
316-
program exits, it calls all remaining live finalizers for which
317-
:attr:`.atexit` is true. They are called in reverse order of
316+
A writable boolean property which by default is true. At
317+
:term:`interpreter shutdown`, all remaining live finalizers for which
318+
:attr:`.atexit` is true are called in reverse order of
318319
creation.
319320

320321
.. note::

0 commit comments

Comments
 (0)