summaryrefslogtreecommitdiff
path: root/Python/errors.c
diff options
context:
space:
mode:
authorMark Shannon <mark@hotpy.org>2017-10-22 22:41:51 +0100
committerAntoine Pitrou <pitrou@free.fr>2017-10-22 23:41:51 +0200
commitae3087c6382011c47db82fea4d05f8bbf514265d (patch)
treec5d832a760d9898700f1ca397a5a305734b3d77a /Python/errors.c
parent91dc64ba3f51100540b2ab6c6cd72c3bb18a6d49 (diff)
downloadcpython-git-ae3087c6382011c47db82fea4d05f8bbf514265d.tar.gz
Move exc state to generator. Fixes bpo-25612 (#1773)
Move exception state information from frame objects to coroutine (generator/thread) object where it belongs.
Diffstat (limited to 'Python/errors.c')
-rw-r--r--Python/errors.c34
1 files changed, 24 insertions, 10 deletions
diff --git a/Python/errors.c b/Python/errors.c
index 5709fddb58..51fc791f45 100644
--- a/Python/errors.c
+++ b/Python/errors.c
@@ -53,6 +53,18 @@ PyErr_Restore(PyObject *type, PyObject *value, PyObject *traceback)
Py_XDECREF(oldtraceback);
}
+_PyErr_StackItem *
+_PyErr_GetTopmostException(PyThreadState *tstate)
+{
+ _PyErr_StackItem *exc_info = tstate->exc_info;
+ while ((exc_info->exc_type == NULL || exc_info->exc_type == Py_None) &&
+ exc_info->previous_item != NULL)
+ {
+ exc_info = exc_info->previous_item;
+ }
+ return exc_info;
+}
+
static PyObject*
_PyErr_CreateException(PyObject *exception, PyObject *value)
{
@@ -83,7 +95,7 @@ PyErr_SetObject(PyObject *exception, PyObject *value)
}
Py_XINCREF(value);
- exc_value = tstate->exc_value;
+ exc_value = _PyErr_GetTopmostException(tstate)->exc_value;
if (exc_value != NULL && exc_value != Py_None) {
/* Implicit exception chaining */
Py_INCREF(exc_value);
@@ -335,9 +347,11 @@ PyErr_GetExcInfo(PyObject **p_type, PyObject **p_value, PyObject **p_traceback)
{
PyThreadState *tstate = PyThreadState_GET();
- *p_type = tstate->exc_type;
- *p_value = tstate->exc_value;
- *p_traceback = tstate->exc_traceback;
+ _PyErr_StackItem *exc_info = _PyErr_GetTopmostException(tstate);
+ *p_type = exc_info->exc_type;
+ *p_value = exc_info->exc_value;
+ *p_traceback = exc_info->exc_traceback;
+
Py_XINCREF(*p_type);
Py_XINCREF(*p_value);
@@ -350,13 +364,13 @@ PyErr_SetExcInfo(PyObject *p_type, PyObject *p_value, PyObject *p_traceback)
PyObject *oldtype, *oldvalue, *oldtraceback;
PyThreadState *tstate = PyThreadState_GET();
- oldtype = tstate->exc_type;
- oldvalue = tstate->exc_value;
- oldtraceback = tstate->exc_traceback;
+ oldtype = tstate->exc_info->exc_type;
+ oldvalue = tstate->exc_info->exc_value;
+ oldtraceback = tstate->exc_info->exc_traceback;
- tstate->exc_type = p_type;
- tstate->exc_value = p_value;
- tstate->exc_traceback = p_traceback;
+ tstate->exc_info->exc_type = p_type;
+ tstate->exc_info->exc_value = p_value;
+ tstate->exc_info->exc_traceback = p_traceback;
Py_XDECREF(oldtype);
Py_XDECREF(oldvalue);