You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
106 lines
4.2 KiB
106 lines
4.2 KiB
diff --git a/Doc/whatsnew/3.6.rst b/Doc/whatsnew/3.6.rst |
|
index 847b50140a6..570dc3ed6fe 100644 |
|
--- a/Doc/whatsnew/3.6.rst |
|
+++ b/Doc/whatsnew/3.6.rst |
|
@@ -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 |
|
diff --git a/Include/pyerrors.h b/Include/pyerrors.h |
|
index c28c1373f82..8c1dbc5047b 100644 |
|
--- a/Include/pyerrors.h |
|
+++ b/Include/pyerrors.h |
|
@@ -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; |
|
diff --git a/Misc/NEWS.d/next/C API/2017-12-20-15-23-06.bpo-30697.v9FmgG.rst b/Misc/NEWS.d/next/C API/2017-12-20-15-23-06.bpo-30697.v9FmgG.rst |
|
new file mode 100644 |
|
index 00000000000..28f74ad4f30 |
|
--- /dev/null |
|
+++ b/Misc/NEWS.d/next/C API/2017-12-20-15-23-06.bpo-30697.v9FmgG.rst |
|
@@ -0,0 +1 @@ |
|
+Restore PyExc_RecursionErrorInst in 3.6 |
|
diff --git a/Objects/exceptions.c b/Objects/exceptions.c |
|
index df4899372a5..271e293e325 100644 |
|
--- a/Objects/exceptions.c |
|
+++ b/Objects/exceptions.c |
|
@@ -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) \ |
|
@@ -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); |
|
} |
|
diff --git a/PC/python3.def b/PC/python3.def |
|
index 4fc4a6814ee..ff70718fc37 100644 |
|
--- a/PC/python3.def |
|
+++ b/PC/python3.def |
|
@@ -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
|
|
|