Skip to content

Commit

Permalink
pythongh-108014: Add Py_IsFinalizing() function
Browse files Browse the repository at this point in the history
  • Loading branch information
vstinner committed Aug 16, 2023
1 parent 42429d3 commit e03b437
Show file tree
Hide file tree
Showing 8 changed files with 22 additions and 7 deletions.
14 changes: 11 additions & 3 deletions Doc/c-api/init.rst
Original file line number Diff line number Diff line change
Expand Up @@ -373,6 +373,14 @@ Initializing and finalizing the interpreter
:c:func:`Py_Initialize` is called again.
.. c:function:: int Py_IsFinalizing()
Return non-zero if the Python interpreter is :term:`shutting down
<interpreter shutdown>`, return 0 otherwise.
.. versionadded:: 3.13
.. c:function:: int Py_FinalizeEx()
Undo all initializations made by :c:func:`Py_Initialize` and subsequent use of
Expand Down Expand Up @@ -852,7 +860,7 @@ code, or when embedding the Python interpreter:
.. note::
Calling this function from a thread when the runtime is finalizing
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
this function to avoid unwanted termination.
Expand Down Expand Up @@ -898,7 +906,7 @@ with sub-interpreters:
.. note::
Calling this function from a thread when the runtime is finalizing
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
this function to avoid unwanted termination.
Expand Down Expand Up @@ -1180,7 +1188,7 @@ All of the following functions must be called after :c:func:`Py_Initialize`.
.. note::
Calling this function from a thread when the runtime is finalizing
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
this function to avoid unwanted termination.
Expand Down
4 changes: 4 additions & 0 deletions Doc/whatsnew/3.13.rst
Original file line number Diff line number Diff line change
Expand Up @@ -826,6 +826,10 @@ New Features
not needed.
(Contributed by Victor Stinner in :gh:`106004`.)

* Add :c:func:`Py_IsFinalizing` function: check if the Python interpreter is
:term:`shutting down <interpreter shutdown>`.
(Contributed by Victor Stinner in :gh:`108014`.)

Porting to Python 3.13
----------------------

Expand Down
2 changes: 2 additions & 0 deletions Include/cpython/pylifecycle.h
Original file line number Diff line number Diff line change
Expand Up @@ -81,3 +81,5 @@ PyAPI_FUNC(PyStatus) Py_NewInterpreterFromConfig(
typedef void (*atexit_datacallbackfunc)(void *);
PyAPI_FUNC(int) PyUnstable_AtExit(
PyInterpreterState *, atexit_datacallbackfunc, void *);

PyAPI_FUNC(int) Py_IsFinalizing(void);
1 change: 0 additions & 1 deletion Include/internal/pycore_pylifecycle.h
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,6 @@ extern int _Py_FdIsInteractive(FILE *fp, PyObject *filename);
extern const char* _Py_gitidentifier(void);
extern const char* _Py_gitversion(void);

extern int _Py_IsFinalizing(void);
PyAPI_FUNC(int) _Py_IsInterpreterFinalizing(PyInterpreterState *interp);

/* Random */
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Add :c:func:`Py_IsFinalizing` function: check if the Python interpreter is
:term:`shutting down <interpreter shutdown>`. Patch by Victor Stinner.
2 changes: 1 addition & 1 deletion Modules/_asynciomodule.c
Original file line number Diff line number Diff line change
Expand Up @@ -529,7 +529,7 @@ future_init(FutureObj *fut, PyObject *loop)
}
if (is_true && !_Py_IsInterpreterFinalizing(_PyInterpreterState_GET())) {
/* 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__
method, which is called during the interpreter shutdown and the
traceback module is already unloaded.
Expand Down
2 changes: 1 addition & 1 deletion Python/pylifecycle.c
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ _PyRuntime_Finalize(void)
}

int
_Py_IsFinalizing(void)
Py_IsFinalizing(void)
{
return _PyRuntimeState_GetFinalizing(&_PyRuntime) != NULL;
}
Expand Down
2 changes: 1 addition & 1 deletion Python/sysmodule.c
Original file line number Diff line number Diff line change
Expand Up @@ -2095,7 +2095,7 @@ static PyObject *
sys_is_finalizing_impl(PyObject *module)
/*[clinic end generated code: output=735b5ff7962ab281 input=f0df747a039948a5]*/
{
return PyBool_FromLong(_Py_IsFinalizing());
return PyBool_FromLong(Py_IsFinalizing());
}

#ifdef Py_STATS
Expand Down

0 comments on commit e03b437

Please sign in to comment.