Restore the PyExc_RecursionErrorInst public symbol

This commit is contained in:
Charalampos Stratakis 2018-01-23 17:19:17 +01:00
parent 434d469259
commit d623e929ca
2 changed files with 117 additions and 1 deletions

View File

@ -0,0 +1,106 @@
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

View File

@ -14,7 +14,7 @@ URL: https://www.python.org/
# WARNING When rebasing to a new Python version,
# remember to update the python3-docs package as well
Version: %{pybasever}.4
Release: 8%{?dist}
Release: 9%{?dist}
License: Python
@ -372,6 +372,12 @@ Patch290: 00290-cryptmodule-Include-crypt.h-for-declaration-of-crypt.patch
# and: https://src.fedoraproject.org/rpms/redhat-rpm-config/c/078af19
Patch291: 00291-setup-Link-ctypes-against-dl-explicitly.patch
# 00292 #
# Restore the public PyExc_RecursionErrorInst symbol that was removed
# from the 3.6.4 release upstream.
# Reported upstream: https://bugs.python.org/issue30697
Patch292: 00292-restore-PyExc_RecursionErrorInst-symbol.patch
# (New patches go here ^^^)
#
# When adding new patches to "python" and "python3" in Fedora, EL, etc.,
@ -640,6 +646,7 @@ sed -r -i s/'_PIP_VERSION = "[0-9.]+"'/'_PIP_VERSION = "%{pip_version}"'/ Lib/en
%patch289 -p1
%patch290 -p1
%patch291 -p1
%patch292 -p1
# Remove files that should be generated by the build
@ -1504,6 +1511,9 @@ fi
# ======================================================
%changelog
* Tue Jan 23 2018 Charalampos Stratakis <cstratak@redhat.com> - 3.6.4-9
- Restore the PyExc_RecursionErrorInst public symbol
* Tue Jan 23 2018 Björn Esser <besser82@fedoraproject.org> - 3.6.4-8
- Add patch to explicitly link _ctypes module with -ldl (#1537489)
- Refactored patch for libxcrypt