diff options
author | Guido van Rossum <guido@python.org> | 2008-06-14 20:20:24 (GMT) |
---|---|---|
committer | Guido van Rossum <guido@python.org> | 2008-06-14 20:20:24 (GMT) |
commit | b4fb6e4d27b56c2119bd1dad83afce874e34a72a (patch) | |
tree | 8d3d70b49164329da4a47c9d08364f18018b16df /Python/errors.c | |
parent | 973124fd70687f6032a1d6e3a0b9e640d2691133 (diff) | |
download | cpython-b4fb6e4d27b56c2119bd1dad83afce874e34a72a.zip cpython-b4fb6e4d27b56c2119bd1dad83afce874e34a72a.tar.gz cpython-b4fb6e4d27b56c2119bd1dad83afce874e34a72a.tar.bz2 |
Implicit exception chaining via __context__ (PEP 3134).
Patch 3108 by Antooine Pitrou.
Diffstat (limited to 'Python/errors.c')
-rw-r--r-- | Python/errors.c | 33 |
1 files changed, 31 insertions, 2 deletions
diff --git a/Python/errors.c b/Python/errors.c index b765b03..ac64b6a 100644 --- a/Python/errors.c +++ b/Python/errors.c @@ -52,6 +52,9 @@ PyErr_Restore(PyObject *type, PyObject *value, PyObject *traceback) void PyErr_SetObject(PyObject *exception, PyObject *value) { + PyThreadState *tstate = PyThreadState_GET(); + PyObject *tb = NULL; + if (exception != NULL && !PyExceptionClass_Check(exception)) { PyErr_Format(PyExc_SystemError, @@ -59,9 +62,35 @@ PyErr_SetObject(PyObject *exception, PyObject *value) exception); return; } - Py_XINCREF(exception); Py_XINCREF(value); - PyErr_Restore(exception, value, (PyObject *)NULL); + if (tstate->exc_value != NULL && tstate->exc_value != Py_None) { + /* Implicit exception chaining */ + if (value == NULL || !PyExceptionInstance_Check(value)) { + /* We must normalize the value right now */ + PyObject *args, *fixed_value; + if (value == NULL || value == Py_None) + args = PyTuple_New(0); + else if (PyTuple_Check(value)) { + Py_INCREF(value); + args = value; + } + else + args = PyTuple_Pack(1, value); + fixed_value = args ? + PyEval_CallObject(exception, args) : NULL; + Py_XDECREF(args); + Py_XDECREF(value); + if (fixed_value == NULL) + return; + value = fixed_value; + } + Py_INCREF(tstate->exc_value); + PyException_SetContext(value, tstate->exc_value); + } + if (value != NULL && PyExceptionInstance_Check(value)) + tb = PyException_GetTraceback(value); + Py_XINCREF(exception); + PyErr_Restore(exception, value, tb); } void |