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 1 commit
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 non-zero if the Python interpreter is :term:`shutting down
<interpreter shutdown>`, return 0 otherwise.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this referring to the runtime (AKA main interpreter) or to the current interpreter? I'd expect it to be the current interpreter.

Would it make sense to explicitly pass an interpreter and use NULL to mean the current one (or main)?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I copied the documentation of the sys.is_finalizing() function. If you want a different feature (pass an interpreter), I would prefer to have a different function.

It's set by Py_Finalize() which finalizes the main interpreter: other sub-interpreters should be deleted before explicitly, no?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I updated the doc to specify that we are talking about the main interpreter.


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