handling in C, most floating point operations are not checked.
+.. exception:: PythonFinalizationError
+
+ This exception is derived from :exc:`RuntimeError`. It is raised when
+ an operation is blocked during interpreter shutdown also known as
+ :term:`Python finalization <interpreter shutdown>`.
+
+ Examples of operations which can be blocked with a
+ :exc:`PythonFinalizationError` during the Python finalization:
+
+ * Creating a new Python thread.
+ * :func:`os.fork`.
+
+ See also the :func:`sys.is_finalizing` function.
+
+ .. versionadded:: 3.13
+ Previously, a plain :exc:`RuntimeError` was raised.
+
+
.. exception:: RecursionError
This exception is derived from :exc:`RuntimeError`. It is raised when the
Return :const:`True` if the main Python interpreter is
:term:`shutting down <interpreter shutdown>`. Return :const:`False` otherwise.
+ See also the :exc:`PythonFinalizationError` exception.
+
.. versionadded:: 3.5
.. data:: last_exc
(Contributed by Levi Sabah, Zackery Spytz and Hugo van Kemenade in
:gh:`73965`.)
+* Add :exc:`PythonFinalizationError` exception. This exception derived from
+ :exc:`RuntimeError` is raised when an operation is blocked during
+ the :term:`Python finalization <interpreter shutdown>`.
+
+ The following functions now raise PythonFinalizationError, instead of
+ :exc:`RuntimeError`:
+
+ * :func:`_thread.start_new_thread`.
+ * :class:`subprocess.Popen`.
+ * :func:`os.fork`.
+ * :func:`os.forkpty`.
+
+ (Contributed by Victor Stinner in :gh:`114570`.)
+
+
New Modules
===========
PyAPI_FUNC(void) PyErr_FormatUnraisable(const char *, ...);
+PyAPI_DATA(PyObject *) PyExc_PythonFinalizationError;
+
#define Py_FatalError(message) _Py_FatalErrorFunc(__func__, (message))
├── ReferenceError
├── RuntimeError
│ ├── NotImplementedError
+ │ ├── PythonFinalizationError
│ └── RecursionError
├── StopAsyncIteration
├── StopIteration
if exc in (BlockingIOError,
ResourceWarning,
StopAsyncIteration,
+ PythonFinalizationError,
RecursionError,
EncodingWarning,
BaseExceptionGroup,
--- /dev/null
+Add :exc:`PythonFinalizationError` exception. This exception derived from
+:exc:`RuntimeError` is raised when an operation is blocked during the
+:term:`Python finalization <interpreter shutdown>`. Patch by Victor Stinner.
PyInterpreterState *interp = _PyInterpreterState_GET();
if ((preexec_fn != Py_None) && interp->finalizing) {
- PyErr_SetString(PyExc_RuntimeError,
+ PyErr_SetString(PyExc_PythonFinalizationError,
"preexec_fn not supported at interpreter shutdown");
return NULL;
}
return -1;
}
if (interp->finalizing) {
- PyErr_SetString(PyExc_RuntimeError,
+ PyErr_SetString(PyExc_PythonFinalizationError,
"can't create new thread at interpreter shutdown");
return -1;
}
{
/* The operation is still pending -- give a warning. This
will probably only happen on Windows XP. */
- PyErr_SetString(PyExc_RuntimeError,
+ PyErr_SetString(PyExc_PythonFinalizationError,
"I/O operations still in flight while destroying "
"Overlapped object, the process may crash");
PyErr_WriteUnraisable(NULL);
PyInterpreterState *interp = _PyInterpreterState_GET();
if (interp->finalizing) {
- PyErr_SetString(PyExc_RuntimeError,
+ PyErr_SetString(PyExc_PythonFinalizationError,
"can't fork at interpreter shutdown");
return NULL;
}
pid_t pid;
PyInterpreterState *interp = _PyInterpreterState_GET();
if (interp->finalizing) {
- PyErr_SetString(PyExc_RuntimeError,
+ PyErr_SetString(PyExc_PythonFinalizationError,
"can't fork at interpreter shutdown");
return NULL;
}
PyInterpreterState *interp = _PyInterpreterState_GET();
if (interp->finalizing) {
- PyErr_SetString(PyExc_RuntimeError,
+ PyErr_SetString(PyExc_PythonFinalizationError,
"can't fork at interpreter shutdown");
return NULL;
}
SimpleExtendsException(PyExc_RuntimeError, RecursionError,
"Recursion limit exceeded.");
+// PythonFinalizationError extends RuntimeError
+SimpleExtendsException(PyExc_RuntimeError, PythonFinalizationError,
+ "Operation blocked during Python finalization.");
+
/*
* NotImplementedError extends RuntimeError
*/
ITEM(KeyError), // base: LookupError(Exception)
ITEM(ModuleNotFoundError), // base: ImportError(Exception)
ITEM(NotImplementedError), // base: RuntimeError(Exception)
+ ITEM(PythonFinalizationError), // base: RuntimeError(Exception)
ITEM(RecursionError), // base: RuntimeError(Exception)
ITEM(UnboundLocalError), // base: NameError(Exception)
ITEM(UnicodeError), // base: ValueError(Exception)
Objects/exceptions.c - _PyExc_TimeoutError -
Objects/exceptions.c - _PyExc_EOFError -
Objects/exceptions.c - _PyExc_RuntimeError -
+Objects/exceptions.c - _PyExc_PythonFinalizationError -
Objects/exceptions.c - _PyExc_RecursionError -
Objects/exceptions.c - _PyExc_NotImplementedError -
Objects/exceptions.c - _PyExc_NameError -
Objects/exceptions.c - PyExc_TimeoutError -
Objects/exceptions.c - PyExc_EOFError -
Objects/exceptions.c - PyExc_RuntimeError -
+Objects/exceptions.c - PyExc_PythonFinalizationError -
Objects/exceptions.c - PyExc_RecursionError -
Objects/exceptions.c - PyExc_NotImplementedError -
Objects/exceptions.c - PyExc_NameError -