Skip to content

gh-108014: Add Py_IsFinalizing() function #108032

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Aug 18, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 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()

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: 2 additions & 2 deletions Doc/library/sys.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1121,8 +1121,8 @@ always available.

.. function:: is_finalizing()

Return :const:`True` if the Python interpreter is
:term:`shutting down <interpreter shutdown>`, :const:`False` otherwise.
Return :const:`True` if the main Python interpreter is
:term:`shutting down <interpreter shutdown>`. Return :const:`False` otherwise.

.. versionadded:: 3.5

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 main 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 main 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