Mercurial > cpython-lru_cache-weakref
diff Python/errors.c @ 47722:7ba7901dad7f
Implicit exception chaining via __context__ (PEP 3134).
Patch 3108 by Antooine Pitrou.
| author | Guido van Rossum <guido@python.org> |
|---|---|
| date | Sat, 14 Jun 2008 20:20:24 +0000 |
| parents | 47d9bbe10897 |
| children | 2ee09afee126 |
line wrap: on
line diff
--- a/Python/errors.c Sat Jun 14 12:03:33 2008 +0000 +++ b/Python/errors.c Sat Jun 14 20:20:24 2008 +0000 @@ -52,6 +52,9 @@ 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 @@ exception); return; } + Py_XINCREF(value); + 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); - Py_XINCREF(value); - PyErr_Restore(exception, value, (PyObject *)NULL); + PyErr_Restore(exception, value, tb); } void
