comparison Python/pythonrun.c @ 17164:b44e77a12978 legacy-trunk

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__.
author Ka-Ping Yee <ping@zesty.ca>
date Fri, 23 Mar 2001 02:46:52 +0000
parents 2054cea38754
children 0d52358cb288
comparison
equal deleted inserted replaced
17163:ad683f20bb14 17164:b44e77a12978
799 } 799 }
800 800
801 void 801 void
802 PyErr_PrintEx(int set_sys_last_vars) 802 PyErr_PrintEx(int set_sys_last_vars)
803 { 803 {
804 int err = 0; 804 PyObject *exception, *v, *tb, *hook;
805 PyObject *exception, *v, *tb, *f;
806 PyErr_Fetch(&exception, &v, &tb); 805 PyErr_Fetch(&exception, &v, &tb);
807 PyErr_NormalizeException(&exception, &v, &tb); 806 PyErr_NormalizeException(&exception, &v, &tb);
808 807
809 if (exception == NULL) 808 if (exception == NULL)
810 return; 809 return;
843 if (set_sys_last_vars) { 842 if (set_sys_last_vars) {
844 PySys_SetObject("last_type", exception); 843 PySys_SetObject("last_type", exception);
845 PySys_SetObject("last_value", v); 844 PySys_SetObject("last_value", v);
846 PySys_SetObject("last_traceback", tb); 845 PySys_SetObject("last_traceback", tb);
847 } 846 }
848 f = PySys_GetObject("stderr"); 847 hook = PySys_GetObject("excepthook");
848 if (hook) {
849 PyObject *args = Py_BuildValue("(OOO)",
850 exception, v ? v : Py_None, tb ? tb : Py_None);
851 PyObject *result = PyEval_CallObject(hook, args);
852 if (result == NULL) {
853 PyObject *exception2, *v2, *tb2;
854 PyErr_Fetch(&exception2, &v2, &tb2);
855 PyErr_NormalizeException(&exception2, &v2, &tb2);
856 if (Py_FlushLine())
857 PyErr_Clear();
858 fflush(stdout);
859 PySys_WriteStderr("Error in sys.excepthook:\n");
860 PyErr_Display(exception2, v2, tb2);
861 PySys_WriteStderr("\nOriginal exception was:\n");
862 PyErr_Display(exception, v, tb);
863 }
864 Py_XDECREF(result);
865 Py_XDECREF(args);
866 } else {
867 PySys_WriteStderr("sys.excepthook is missing\n");
868 PyErr_Display(exception, v, tb);
869 }
870 Py_XDECREF(exception);
871 Py_XDECREF(v);
872 Py_XDECREF(tb);
873 }
874
875 void PyErr_Display(PyObject *exception, PyObject *value, PyObject *tb)
876 {
877 int err = 0;
878 PyObject *v = value;
879 PyObject *f = PySys_GetObject("stderr");
849 if (f == NULL) 880 if (f == NULL)
850 fprintf(stderr, "lost sys.stderr\n"); 881 fprintf(stderr, "lost sys.stderr\n");
851 else { 882 else {
852 if (Py_FlushLine()) 883 if (Py_FlushLine())
853 PyErr_Clear(); 884 PyErr_Clear();
854 fflush(stdout); 885 fflush(stdout);
855 err = PyTraceBack_Print(tb, f); 886 if (tb && tb != Py_None)
887 err = PyTraceBack_Print(tb, f);
856 if (err == 0 && 888 if (err == 0 &&
857 PyErr_GivenExceptionMatches(exception, PyExc_SyntaxError)) 889 PyErr_GivenExceptionMatches(exception, PyExc_SyntaxError))
858 { 890 {
859 PyObject *message; 891 PyObject *message;
860 char *filename, *text; 892 char *filename, *text;
873 sprintf(buf, "%d", lineno); 905 sprintf(buf, "%d", lineno);
874 PyFile_WriteString(buf, f); 906 PyFile_WriteString(buf, f);
875 PyFile_WriteString("\n", f); 907 PyFile_WriteString("\n", f);
876 if (text != NULL) 908 if (text != NULL)
877 print_error_text(f, offset, text); 909 print_error_text(f, offset, text);
878 Py_INCREF(message);
879 Py_DECREF(v);
880 v = message; 910 v = message;
881 /* Can't be bothered to check all those 911 /* Can't be bothered to check all those
882 PyFile_WriteString() calls */ 912 PyFile_WriteString() calls */
883 if (PyErr_Occurred()) 913 if (PyErr_Occurred())
884 err = -1; 914 err = -1;
930 } 960 }
931 } 961 }
932 if (err == 0) 962 if (err == 0)
933 err = PyFile_WriteString("\n", f); 963 err = PyFile_WriteString("\n", f);
934 } 964 }
935 Py_XDECREF(exception);
936 Py_XDECREF(v);
937 Py_XDECREF(tb);
938 /* If an error happened here, don't show it. 965 /* If an error happened here, don't show it.
939 XXX This is wrong, but too many callers rely on this behavior. */ 966 XXX This is wrong, but too many callers rely on this behavior. */
940 if (err != 0) 967 if (err != 0)
941 PyErr_Clear(); 968 PyErr_Clear();
942 } 969 }