diff options
author | Ka-Ping Yee <ping@zesty.ca> | 2001-03-23 02:46:52 (GMT) |
---|---|---|
committer | Ka-Ping Yee <ping@zesty.ca> | 2001-03-23 02:46:52 (GMT) |
commit | b5c5132d1ac526dc97f8c51ef12299bde791a807 (patch) | |
tree | 68d6dbc1068e0a16051530564b789148cfb516cb /Python/pythonrun.c | |
parent | 37f7b38eb6247564c00c8a355ab12268e8486c4e (diff) | |
download | cpython-b5c5132d1ac526dc97f8c51ef12299bde791a807.zip cpython-b5c5132d1ac526dc97f8c51ef12299bde791a807.tar.gz cpython-b5c5132d1ac526dc97f8c51ef12299bde791a807.tar.bz2 |
Add sys.excepthook.
Update docstring and library reference section on 'sys' module.
New API PyErr_Display, just for displaying errors, called by excepthook.
Uncaught exceptions now call sys.excepthook; if that fails, we fall back
to calling PyErr_Display directly.
Also comes with sys.__excepthook__ and sys.__displayhook__.
Diffstat (limited to 'Python/pythonrun.c')
-rw-r--r-- | Python/pythonrun.c | 45 |
1 files changed, 36 insertions, 9 deletions
diff --git a/Python/pythonrun.c b/Python/pythonrun.c index edb8a11..6fa85ac 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -801,8 +801,7 @@ print_error_text(PyObject *f, int offset, char *text) void PyErr_PrintEx(int set_sys_last_vars) { - int err = 0; - PyObject *exception, *v, *tb, *f; + PyObject *exception, *v, *tb, *hook; PyErr_Fetch(&exception, &v, &tb); PyErr_NormalizeException(&exception, &v, &tb); @@ -845,14 +844,47 @@ PyErr_PrintEx(int set_sys_last_vars) PySys_SetObject("last_value", v); PySys_SetObject("last_traceback", tb); } - f = PySys_GetObject("stderr"); + hook = PySys_GetObject("excepthook"); + if (hook) { + PyObject *args = Py_BuildValue("(OOO)", + exception, v ? v : Py_None, tb ? tb : Py_None); + PyObject *result = PyEval_CallObject(hook, args); + if (result == NULL) { + PyObject *exception2, *v2, *tb2; + PyErr_Fetch(&exception2, &v2, &tb2); + PyErr_NormalizeException(&exception2, &v2, &tb2); + if (Py_FlushLine()) + PyErr_Clear(); + fflush(stdout); + PySys_WriteStderr("Error in sys.excepthook:\n"); + PyErr_Display(exception2, v2, tb2); + PySys_WriteStderr("\nOriginal exception was:\n"); + PyErr_Display(exception, v, tb); + } + Py_XDECREF(result); + Py_XDECREF(args); + } else { + PySys_WriteStderr("sys.excepthook is missing\n"); + PyErr_Display(exception, v, tb); + } + Py_XDECREF(exception); + Py_XDECREF(v); + Py_XDECREF(tb); +} + +void PyErr_Display(PyObject *exception, PyObject *value, PyObject *tb) +{ + int err = 0; + PyObject *v = value; + PyObject *f = PySys_GetObject("stderr"); if (f == NULL) fprintf(stderr, "lost sys.stderr\n"); else { if (Py_FlushLine()) PyErr_Clear(); fflush(stdout); - err = PyTraceBack_Print(tb, f); + if (tb && tb != Py_None) + err = PyTraceBack_Print(tb, f); if (err == 0 && PyErr_GivenExceptionMatches(exception, PyExc_SyntaxError)) { @@ -875,8 +907,6 @@ PyErr_PrintEx(int set_sys_last_vars) PyFile_WriteString("\n", f); if (text != NULL) print_error_text(f, offset, text); - Py_INCREF(message); - Py_DECREF(v); v = message; /* Can't be bothered to check all those PyFile_WriteString() calls */ @@ -932,9 +962,6 @@ PyErr_PrintEx(int set_sys_last_vars) if (err == 0) err = PyFile_WriteString("\n", f); } - Py_XDECREF(exception); - Py_XDECREF(v); - Py_XDECREF(tb); /* If an error happened here, don't show it. XXX This is wrong, but too many callers rely on this behavior. */ if (err != 0) |