Skip to content
Closed
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
8 changes: 4 additions & 4 deletions Doc/whatsnew/3.6.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1852,10 +1852,10 @@ Build and C API Changes
* The :c:func:`PyUnicode_FSConverter` and :c:func:`PyUnicode_FSDecoder`
functions will now accept :term:`path-like objects <path-like object>`.

* The ``PyExc_RecursionErrorInst`` singleton that was part of the public API
has been removed as its members being never cleared may cause a segfault
during finalization of the interpreter. Contributed by Xavier de Gaye in
:issue:`22898` and :issue:`30697`.
* The ``PyExc_RecursionErrorInst`` singleton is not used anymore as its members
being never cleared may cause a segfault during finalization of the
interpreter. Contributed by Xavier de Gaye in :issue:`22898` and
:issue:`30697`.


Other Improvements
Expand Down
2 changes: 2 additions & 0 deletions Include/pyerrors.h
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,8 @@ PyAPI_DATA(PyObject *) PyExc_IOError;
PyAPI_DATA(PyObject *) PyExc_WindowsError;
#endif

PyAPI_DATA(PyObject *) PyExc_RecursionErrorInst;

/* Predefined warning categories */
PyAPI_DATA(PyObject *) PyExc_Warning;
PyAPI_DATA(PyObject *) PyExc_UserWarning;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Restore PyExc_RecursionErrorInst in 3.6
32 changes: 32 additions & 0 deletions Objects/exceptions.c
Original file line number Diff line number Diff line change
Expand Up @@ -2430,6 +2430,12 @@ SimpleExtendsException(PyExc_Warning, ResourceWarning,



/* Pre-computed RecursionError instance for when recursion depth is reached.
Meant to be used when normalizing the exception for exceeding the recursion
depth will cause its own infinite recursion.
*/
PyObject *PyExc_RecursionErrorInst = NULL;

#define PRE_INIT(TYPE) \
if (!(_PyExc_ ## TYPE.tp_flags & Py_TPFLAGS_READY)) { \
if (PyType_Ready(&_PyExc_ ## TYPE) < 0) \
Expand Down Expand Up @@ -2691,11 +2697,37 @@ _PyExc_Init(PyObject *bltinmod)
ADD_ERRNO(TimeoutError, ETIMEDOUT);

preallocate_memerrors();

if (!PyExc_RecursionErrorInst) {
PyExc_RecursionErrorInst = BaseException_new(&_PyExc_RecursionError, NULL, NULL);
if (!PyExc_RecursionErrorInst)
Py_FatalError("Cannot pre-allocate RecursionError instance for "
"recursion errors");
else {
PyBaseExceptionObject *err_inst =
(PyBaseExceptionObject *)PyExc_RecursionErrorInst;
PyObject *args_tuple;
PyObject *exc_message;
exc_message = PyUnicode_FromString("maximum recursion depth exceeded");
if (!exc_message)
Py_FatalError("cannot allocate argument for RecursionError "
"pre-allocation");
args_tuple = PyTuple_Pack(1, exc_message);
if (!args_tuple)
Py_FatalError("cannot allocate tuple for RecursionError "
"pre-allocation");
Py_DECREF(exc_message);
if (BaseException_init(err_inst, args_tuple, NULL))
Py_FatalError("init of pre-allocated RecursionError failed");
Py_DECREF(args_tuple);
}
}
}

void
_PyExc_Fini(void)
{
Py_CLEAR(PyExc_RecursionErrorInst);
free_preallocated_memerrors();
Py_CLEAR(errnomap);
}
Expand Down
1 change: 1 addition & 0 deletions PC/python3.def
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,7 @@ EXPORTS
PyExc_PermissionError=python36.PyExc_PermissionError DATA
PyExc_ProcessLookupError=python36.PyExc_ProcessLookupError DATA
PyExc_RecursionError=python36.PyExc_RecursionError DATA
PyExc_RecursionErrorInst=python36.PyExc_RecursionErrorInst DATA
PyExc_ReferenceError=python36.PyExc_ReferenceError DATA
PyExc_ResourceWarning=python36.PyExc_ResourceWarning DATA
PyExc_RuntimeError=python36.PyExc_RuntimeError DATA
Expand Down