summaryrefslogtreecommitdiffstats
path: root/Python
diff options
context:
space:
mode:
authorJeremy Hylton <jeremy@alum.mit.edu>2001-09-26 19:58:38 (GMT)
committerJeremy Hylton <jeremy@alum.mit.edu>2001-09-26 19:58:38 (GMT)
commite2e2c9f41e13d81c6650ae4f4b4ff15a3e6d9423 (patch)
tree68f7c3b4b45c85158e24573336689da64e3e2f2b /Python
parent4f38c1e6643397135563aa365f8d0c0315ab70e7 (diff)
downloadcpython-e2e2c9f41e13d81c6650ae4f4b4ff15a3e6d9423.zip
cpython-e2e2c9f41e13d81c6650ae4f4b4ff15a3e6d9423.tar.gz
cpython-e2e2c9f41e13d81c6650ae4f4b4ff15a3e6d9423.tar.bz2
PyErr_NormalizeException()
If a new exception occurs while an exception instance is being created, try harder to make sure there is a traceback. If the original exception had a traceback associated with it and the new exception does not, keep the old exception. Of course, callers to PyErr_NormalizeException() must still be prepared to have tb set to NULL. XXX This isn't an ideal solution, but it's better than no traceback at all. It occurs if, for example, the exception occurs when the call to the constructor fails before any Python code is executed. Guido suggests that it there is Python code that was about to be executed -- but wasn't, say, because it was called with the wrong number of arguments -- then we should point at the first line of the code object anyway.
Diffstat (limited to 'Python')
-rw-r--r--Python/errors.c13
1 files changed, 12 insertions, 1 deletions
diff --git a/Python/errors.c b/Python/errors.c
index 8a4568f..c37d86b 100644
--- a/Python/errors.c
+++ b/Python/errors.c
@@ -128,6 +128,7 @@ PyErr_NormalizeException(PyObject **exc, PyObject **val, PyObject **tb)
PyObject *type = *exc;
PyObject *value = *val;
PyObject *inclass = NULL;
+ PyObject *initial_tb = NULL;
if (type == NULL) {
/* This is a bug. Should never happen. Don't dump core. */
@@ -191,8 +192,18 @@ PyErr_NormalizeException(PyObject **exc, PyObject **val, PyObject **tb)
finally:
Py_DECREF(type);
Py_DECREF(value);
- Py_XDECREF(*tb);
+ /* If the new exception doesn't set a traceback and the old
+ exception had a traceback, use the old traceback for the
+ new exception. It's better than nothing.
+ */
+ initial_tb = *tb;
PyErr_Fetch(exc, val, tb);
+ if (initial_tb != NULL) {
+ if (*tb == NULL)
+ *tb = initial_tb;
+ else
+ Py_DECREF(initial_tb);
+ }
/* normalize recursively */
PyErr_NormalizeException(exc, val, tb);
}