gh-108014: Add Py_IsFinalizing() function (#108032)

Co-authored-by: Serhiy Storchaka <storchaka@gmail.com>
This commit is contained in:
Victor Stinner 2023-08-18 12:34:41 +02:00 committed by GitHub
parent cc58ec9724
commit 3ff5ef2ad3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 24 additions and 9 deletions

View file

@ -373,6 +373,14 @@ Initializing and finalizing the interpreter
:c:func:`Py_Initialize` is called again. :c:func:`Py_Initialize` is called again.
.. c:function:: int Py_IsFinalizing()
Return true (non-zero) if the main Python interpreter is
:term:`shutting down <interpreter shutdown>`. Return false (zero) otherwise.
.. versionadded:: 3.13
.. c:function:: int Py_FinalizeEx() .. c:function:: int Py_FinalizeEx()
Undo all initializations made by :c:func:`Py_Initialize` and subsequent use of Undo all initializations made by :c:func:`Py_Initialize` and subsequent use of
@ -852,7 +860,7 @@ code, or when embedding the Python interpreter:
.. note:: .. note::
Calling this function from a thread when the runtime is finalizing Calling this function from a thread when the runtime is finalizing
will terminate the thread, even if the thread was not created by Python. will terminate the thread, even if the thread was not created by Python.
You can use :c:func:`!_Py_IsFinalizing` or :func:`sys.is_finalizing` to You can use :c:func:`Py_IsFinalizing` or :func:`sys.is_finalizing` to
check if the interpreter is in process of being finalized before calling check if the interpreter is in process of being finalized before calling
this function to avoid unwanted termination. this function to avoid unwanted termination.
@ -898,7 +906,7 @@ with sub-interpreters:
.. note:: .. note::
Calling this function from a thread when the runtime is finalizing Calling this function from a thread when the runtime is finalizing
will terminate the thread, even if the thread was not created by Python. will terminate the thread, even if the thread was not created by Python.
You can use :c:func:`!_Py_IsFinalizing` or :func:`sys.is_finalizing` to You can use :c:func:`Py_IsFinalizing` or :func:`sys.is_finalizing` to
check if the interpreter is in process of being finalized before calling check if the interpreter is in process of being finalized before calling
this function to avoid unwanted termination. this function to avoid unwanted termination.
@ -1180,7 +1188,7 @@ All of the following functions must be called after :c:func:`Py_Initialize`.
.. note:: .. note::
Calling this function from a thread when the runtime is finalizing Calling this function from a thread when the runtime is finalizing
will terminate the thread, even if the thread was not created by Python. will terminate the thread, even if the thread was not created by Python.
You can use :c:func:`!_Py_IsFinalizing` or :func:`sys.is_finalizing` to You can use :c:func:`Py_IsFinalizing` or :func:`sys.is_finalizing` to
check if the interpreter is in process of being finalized before calling check if the interpreter is in process of being finalized before calling
this function to avoid unwanted termination. this function to avoid unwanted termination.

View file

@ -1121,8 +1121,8 @@ always available.
.. function:: is_finalizing() .. function:: is_finalizing()
Return :const:`True` if the Python interpreter is Return :const:`True` if the main Python interpreter is
:term:`shutting down <interpreter shutdown>`, :const:`False` otherwise. :term:`shutting down <interpreter shutdown>`. Return :const:`False` otherwise.
.. versionadded:: 3.5 .. versionadded:: 3.5

View file

@ -832,6 +832,10 @@ New Features
not needed. not needed.
(Contributed by Victor Stinner in :gh:`106004`.) (Contributed by Victor Stinner in :gh:`106004`.)
* Add :c:func:`Py_IsFinalizing` function: check if the main Python interpreter is
:term:`shutting down <interpreter shutdown>`.
(Contributed by Victor Stinner in :gh:`108014`.)
Porting to Python 3.13 Porting to Python 3.13
---------------------- ----------------------

View file

@ -81,3 +81,5 @@ PyAPI_FUNC(PyStatus) Py_NewInterpreterFromConfig(
typedef void (*atexit_datacallbackfunc)(void *); typedef void (*atexit_datacallbackfunc)(void *);
PyAPI_FUNC(int) PyUnstable_AtExit( PyAPI_FUNC(int) PyUnstable_AtExit(
PyInterpreterState *, atexit_datacallbackfunc, void *); PyInterpreterState *, atexit_datacallbackfunc, void *);
PyAPI_FUNC(int) Py_IsFinalizing(void);

View file

@ -98,7 +98,6 @@ extern int _Py_FdIsInteractive(FILE *fp, PyObject *filename);
extern const char* _Py_gitidentifier(void); extern const char* _Py_gitidentifier(void);
extern const char* _Py_gitversion(void); extern const char* _Py_gitversion(void);
extern int _Py_IsFinalizing(void);
PyAPI_FUNC(int) _Py_IsInterpreterFinalizing(PyInterpreterState *interp); PyAPI_FUNC(int) _Py_IsInterpreterFinalizing(PyInterpreterState *interp);
/* Random */ /* Random */

View file

@ -0,0 +1,2 @@
Add :c:func:`Py_IsFinalizing` function: check if the main Python interpreter is
:term:`shutting down <interpreter shutdown>`. Patch by Victor Stinner.

View file

@ -529,7 +529,7 @@ future_init(FutureObj *fut, PyObject *loop)
} }
if (is_true && !_Py_IsInterpreterFinalizing(_PyInterpreterState_GET())) { if (is_true && !_Py_IsInterpreterFinalizing(_PyInterpreterState_GET())) {
/* Only try to capture the traceback if the interpreter is not being /* Only try to capture the traceback if the interpreter is not being
finalized. The original motivation to add a `_Py_IsFinalizing()` finalized. The original motivation to add a `Py_IsFinalizing()`
call was to prevent SIGSEGV when a Future is created in a __del__ call was to prevent SIGSEGV when a Future is created in a __del__
method, which is called during the interpreter shutdown and the method, which is called during the interpreter shutdown and the
traceback module is already unloaded. traceback module is already unloaded.

View file

@ -129,7 +129,7 @@ _PyRuntime_Finalize(void)
} }
int int
_Py_IsFinalizing(void) Py_IsFinalizing(void)
{ {
return _PyRuntimeState_GetFinalizing(&_PyRuntime) != NULL; return _PyRuntimeState_GetFinalizing(&_PyRuntime) != NULL;
} }

View file

@ -2095,7 +2095,7 @@ static PyObject *
sys_is_finalizing_impl(PyObject *module) sys_is_finalizing_impl(PyObject *module)
/*[clinic end generated code: output=735b5ff7962ab281 input=f0df747a039948a5]*/ /*[clinic end generated code: output=735b5ff7962ab281 input=f0df747a039948a5]*/
{ {
return PyBool_FromLong(_Py_IsFinalizing()); return PyBool_FromLong(Py_IsFinalizing());
} }
#ifdef Py_STATS #ifdef Py_STATS