Issue #22696: Add function :func:`sys.is_finalizing` to know about interpreter shutdown.

This commit is contained in:
Antoine Pitrou 2014-12-07 01:28:27 +01:00
parent b9859daeeb
commit 5db1bb81ff
7 changed files with 62 additions and 6 deletions

View File

@ -402,6 +402,19 @@ Glossary
than compiled ones, though their programs generally also run more than compiled ones, though their programs generally also run more
slowly. See also :term:`interactive`. slowly. See also :term:`interactive`.
interpreter shutdown
When asked to shut down, the Python interpreter enters a special phase
where it gradually releases all allocated resources, such as modules
and various critical internal structures. It also makes several calls
to the :term:`garbage collector <garbage collection>`. This can trigger
the execution of code in user-defined destructors or weakref callbacks.
Code executed during the shutdown phase can encounter various
exceptions as the resources it relies on may not function anymore
(common examples are library modules or the warnings machinery).
The main reason for interpreter shutdown is that the ``__main__`` module
or the script being run has finished executing.
iterable iterable
An object capable of returning its members one at a time. Examples of An object capable of returning its members one at a time. Examples of
iterables include all sequence types (such as :class:`list`, :class:`str`, iterables include all sequence types (such as :class:`list`, :class:`str`,

View File

@ -186,7 +186,7 @@ values but should not rebind them):
added to this list rather than freed. added to this list rather than freed.
.. versionchanged:: 3.2 .. versionchanged:: 3.2
If this list is non-empty at interpreter shutdown, a If this list is non-empty at :term:`interpreter shutdown`, a
:exc:`ResourceWarning` is emitted, which is silent by default. If :exc:`ResourceWarning` is emitted, which is silent by default. If
:const:`DEBUG_UNCOLLECTABLE` is set, in addition all uncollectable objects :const:`DEBUG_UNCOLLECTABLE` is set, in addition all uncollectable objects
are printed. are printed.
@ -252,8 +252,8 @@ The following constants are provided for use with :func:`set_debug`:
to the ``garbage`` list. to the ``garbage`` list.
.. versionchanged:: 3.2 .. versionchanged:: 3.2
Also print the contents of the :data:`garbage` list at interpreter Also print the contents of the :data:`garbage` list at
shutdown, if it isn't empty. :term:`interpreter shutdown`, if it isn't empty.
.. data:: DEBUG_SAVEALL .. data:: DEBUG_SAVEALL

View File

@ -718,6 +718,14 @@ always available.
value of :func:`intern` around to benefit from it. value of :func:`intern` around to benefit from it.
.. function:: is_finalizing()
Return :const:`True` if the Python interpreter is
:term:`shutting down <interpreter shutdown>`, :const:`False` otherwise.
.. versionadded:: 3.5
.. data:: last_type .. data:: last_type
last_value last_value
last_traceback last_traceback

View File

@ -258,7 +258,7 @@ These method have the same issues as the and :meth:`keyrefs` method of
are called in reverse order of creation. are called in reverse order of creation.
A finalizer will never invoke its callback during the later part of A finalizer will never invoke its callback during the later part of
the interpreter shutdown when module globals are liable to have the :term:`interpreter shutdown` when module globals are liable to have
been replaced by :const:`None`. been replaced by :const:`None`.
.. method:: __call__() .. method:: __call__()
@ -527,8 +527,8 @@ follows::
Starting with Python 3.4, :meth:`__del__` methods no longer prevent Starting with Python 3.4, :meth:`__del__` methods no longer prevent
reference cycles from being garbage collected, and module globals are reference cycles from being garbage collected, and module globals are
no longer forced to :const:`None` during interpreter shutdown. So this no longer forced to :const:`None` during :term:`interpreter shutdown`.
code should work without any issues on CPython. So this code should work without any issues on CPython.
However, handling of :meth:`__del__` methods is notoriously implementation However, handling of :meth:`__del__` methods is notoriously implementation
specific, since it depends on internal details of the interpreter's garbage specific, since it depends on internal details of the interpreter's garbage

View File

@ -744,6 +744,27 @@ class SysModuleTest(unittest.TestCase):
c = sys.getallocatedblocks() c = sys.getallocatedblocks()
self.assertIn(c, range(b - 50, b + 50)) self.assertIn(c, range(b - 50, b + 50))
def test_is_finalizing(self):
self.assertIs(sys.is_finalizing(), False)
# Don't use the atexit module because _Py_Finalizing is only set
# after calling atexit callbacks
code = """if 1:
import sys
class AtExit:
is_finalizing = sys.is_finalizing
print = print
def __del__(self):
self.print(self.is_finalizing(), flush=True)
# Keep a reference in the __main__ module namespace, so the
# AtExit destructor will be called at Python exit
ref = AtExit()
"""
rc, stdout, stderr = assert_python_ok('-c', code)
self.assertEqual(stdout.rstrip(), b'True')
@test.support.cpython_only @test.support.cpython_only
class SizeofTest(unittest.TestCase): class SizeofTest(unittest.TestCase):

View File

@ -194,6 +194,9 @@ Core and Builtins
Library Library
------- -------
- Issue #22696: Add function :func:`sys.is_finalizing` to know about
interpreter shutdown.
- Issue #16043: Add a default limit for the amount of data xmlrpclib.gzip_decode - Issue #16043: Add a default limit for the amount of data xmlrpclib.gzip_decode
will return. This resolves CVE-2013-1753. will return. This resolves CVE-2013-1753.

View File

@ -1121,6 +1121,16 @@ PyDoc_STRVAR(sys_clear_type_cache__doc__,
"_clear_type_cache() -> None\n\ "_clear_type_cache() -> None\n\
Clear the internal type lookup cache."); Clear the internal type lookup cache.");
static PyObject *
sys_is_finalizing(PyObject* self, PyObject* args)
{
return PyBool_FromLong(_Py_Finalizing != NULL);
}
PyDoc_STRVAR(is_finalizing_doc,
"is_finalizing()\n\
Return True if Python is exiting.");
static PyMethodDef sys_methods[] = { static PyMethodDef sys_methods[] = {
/* Might as well keep this in alphabetic order */ /* Might as well keep this in alphabetic order */
@ -1167,6 +1177,7 @@ static PyMethodDef sys_methods[] = {
getwindowsversion_doc}, getwindowsversion_doc},
#endif /* MS_WINDOWS */ #endif /* MS_WINDOWS */
{"intern", sys_intern, METH_VARARGS, intern_doc}, {"intern", sys_intern, METH_VARARGS, intern_doc},
{"is_finalizing", sys_is_finalizing, METH_NOARGS, is_finalizing_doc},
#ifdef USE_MALLOPT #ifdef USE_MALLOPT
{"mdebug", sys_mdebug, METH_VARARGS}, {"mdebug", sys_mdebug, METH_VARARGS},
#endif #endif