summaryrefslogtreecommitdiff
path: root/Python
diff options
context:
space:
mode:
Diffstat (limited to 'Python')
-rw-r--r--Python/ceval.c9
-rw-r--r--Python/errors.c74
2 files changed, 51 insertions, 32 deletions
diff --git a/Python/ceval.c b/Python/ceval.c
index 0427361a03..c5477b30f7 100644
--- a/Python/ceval.c
+++ b/Python/ceval.c
@@ -5918,20 +5918,17 @@ do_raise(PyThreadState *tstate, PyObject *exc, PyObject *cause)
if (exc == NULL) {
/* Reraise */
_PyErr_StackItem *exc_info = _PyErr_GetTopmostException(tstate);
- PyObject *tb;
- type = exc_info->exc_type;
value = exc_info->exc_value;
- tb = exc_info->exc_traceback;
- assert(((Py_IsNone(value) || value == NULL)) ==
- ((Py_IsNone(type) || type == NULL)));
if (Py_IsNone(value) || value == NULL) {
_PyErr_SetString(tstate, PyExc_RuntimeError,
"No active exception to reraise");
return 0;
}
+ assert(PyExceptionInstance_Check(value));
+ type = PyExceptionInstance_Class(value);
Py_XINCREF(type);
Py_XINCREF(value);
- Py_XINCREF(tb);
+ PyObject *tb = PyException_GetTraceback(value); /* new ref */
_PyErr_Restore(tstate, type, value, tb);
return 1;
}
diff --git a/Python/errors.c b/Python/errors.c
index 6e74d19b78..0a8b5a257f 100644
--- a/Python/errors.c
+++ b/Python/errors.c
@@ -470,6 +470,33 @@ PyErr_Clear(void)
_PyErr_Clear(tstate);
}
+static PyObject*
+get_exc_type(PyObject *exc_value) /* returns a borrowed ref */
+{
+ if (exc_value == NULL || exc_value == Py_None) {
+ return Py_None;
+ }
+ else {
+ assert(PyExceptionInstance_Check(exc_value));
+ PyObject *type = PyExceptionInstance_Class(exc_value);
+ assert(type != NULL);
+ return type;
+ }
+}
+
+static PyObject*
+get_exc_traceback(PyObject *exc_value) /* returns a borrowed ref */
+{
+ if (exc_value == NULL || exc_value == Py_None) {
+ return Py_None;
+ }
+ else {
+ assert(PyExceptionInstance_Check(exc_value));
+ PyObject *tb = PyException_GetTraceback(exc_value);
+ Py_XDECREF(tb);
+ return tb ? tb : Py_None;
+ }
+}
void
_PyErr_GetExcInfo(PyThreadState *tstate,
@@ -477,18 +504,9 @@ _PyErr_GetExcInfo(PyThreadState *tstate,
{
_PyErr_StackItem *exc_info = _PyErr_GetTopmostException(tstate);
+ *p_type = get_exc_type(exc_info->exc_value);
*p_value = exc_info->exc_value;
- *p_traceback = exc_info->exc_traceback;
-
- if (*p_value == NULL || *p_value == Py_None) {
- assert(exc_info->exc_type == NULL || exc_info->exc_type == Py_None);
- *p_type = Py_None;
- }
- else {
- assert(PyExceptionInstance_Check(*p_value));
- assert(exc_info->exc_type == PyExceptionInstance_Class(*p_value));
- *p_type = PyExceptionInstance_Class(*p_value);
- }
+ *p_traceback = get_exc_traceback(exc_info->exc_value);
Py_XINCREF(*p_type);
Py_XINCREF(*p_value);
@@ -504,7 +522,7 @@ PyErr_GetExcInfo(PyObject **p_type, PyObject **p_value, PyObject **p_traceback)
}
void
-PyErr_SetExcInfo(PyObject *p_type, PyObject *p_value, PyObject *p_traceback)
+PyErr_SetExcInfo(PyObject *type, PyObject *value, PyObject *traceback)
{
PyObject *oldtype, *oldvalue, *oldtraceback;
PyThreadState *tstate = _PyThreadState_GET();
@@ -513,9 +531,16 @@ PyErr_SetExcInfo(PyObject *p_type, PyObject *p_value, PyObject *p_traceback)
oldvalue = tstate->exc_info->exc_value;
oldtraceback = tstate->exc_info->exc_traceback;
- tstate->exc_info->exc_type = p_type;
- tstate->exc_info->exc_value = p_value;
- tstate->exc_info->exc_traceback = p_traceback;
+
+ tstate->exc_info->exc_type = get_exc_type(value);
+ Py_XINCREF(tstate->exc_info->exc_type);
+ tstate->exc_info->exc_value = value;
+ tstate->exc_info->exc_traceback = get_exc_traceback(value);
+ Py_XINCREF(tstate->exc_info->exc_traceback);
+
+ /* These args are no longer used, but we still need to steal a ref */
+ Py_XDECREF(type);
+ Py_XDECREF(traceback);
Py_XDECREF(oldtype);
Py_XDECREF(oldvalue);
@@ -527,22 +552,19 @@ PyObject*
_PyErr_StackItemToExcInfoTuple(_PyErr_StackItem *err_info)
{
PyObject *exc_value = err_info->exc_value;
- if (exc_value == NULL) {
- exc_value = Py_None;
- }
- assert(exc_value == Py_None || PyExceptionInstance_Check(exc_value));
+ assert(exc_value == NULL ||
+ exc_value == Py_None ||
+ PyExceptionInstance_Check(exc_value));
- PyObject *exc_type = PyExceptionInstance_Check(exc_value) ?
- PyExceptionInstance_Class(exc_value) :
- Py_None;
+ PyObject *exc_type = get_exc_type(exc_value);
+ PyObject *exc_traceback = get_exc_traceback(exc_value);
return Py_BuildValue(
"(OOO)",
- exc_type,
- exc_value,
- err_info->exc_traceback != NULL ?
- err_info->exc_traceback : Py_None);
+ exc_type ? exc_type : Py_None,
+ exc_value ? exc_value : Py_None,
+ exc_traceback ? exc_traceback : Py_None);
}