comparison Python/pythonrun.c @ 17191:eb06a02e0507 legacy-trunk

Allow sys.excepthook and sys.exitfunc to quietly exit with a sys.exit(). sys.exitfunc gets the last word on the exit status of the program.
author Ka-Ping Yee <ping@zesty.ca>
date Fri, 23 Mar 2001 15:36:41 +0000
parents 0d52358cb288
children 16f145aac2ec
comparison
equal deleted inserted replaced
17190:bacac75d22fd 17191:eb06a02e0507
797 } 797 }
798 PyFile_WriteString("^\n", f); 798 PyFile_WriteString("^\n", f);
799 } 799 }
800 800
801 void 801 void
802 PyRun_HandleSystemExit(PyObject* value)
803 {
804 if (Py_FlushLine())
805 PyErr_Clear();
806 fflush(stdout);
807 if (value == NULL || value == Py_None)
808 Py_Exit(0);
809 if (PyInstance_Check(value)) {
810 /* The error code should be in the `code' attribute. */
811 PyObject *code = PyObject_GetAttrString(value, "code");
812 if (code) {
813 Py_DECREF(value);
814 value = code;
815 if (value == Py_None)
816 Py_Exit(0);
817 }
818 /* If we failed to dig out the 'code' attribute,
819 just let the else clause below print the error. */
820 }
821 if (PyInt_Check(value))
822 Py_Exit((int)PyInt_AsLong(value));
823 else {
824 PyObject_Print(value, stderr, Py_PRINT_RAW);
825 PySys_WriteStderr("\n");
826 Py_Exit(1);
827 }
828 }
829
830 void
802 PyErr_PrintEx(int set_sys_last_vars) 831 PyErr_PrintEx(int set_sys_last_vars)
803 { 832 {
804 PyObject *exception, *v, *tb, *hook; 833 PyObject *exception, *v, *tb, *hook;
805 PyErr_Fetch(&exception, &v, &tb); 834 PyErr_Fetch(&exception, &v, &tb);
806 PyErr_NormalizeException(&exception, &v, &tb); 835 PyErr_NormalizeException(&exception, &v, &tb);
807 836
808 if (exception == NULL) 837 if (exception == NULL)
809 return; 838 return;
810 839
811 if (PyErr_GivenExceptionMatches(exception, PyExc_SystemExit)) { 840 if (PyErr_GivenExceptionMatches(exception, PyExc_SystemExit)) {
812 if (Py_FlushLine()) 841 PyRun_HandleSystemExit(v);
813 PyErr_Clear();
814 fflush(stdout);
815 if (v == NULL || v == Py_None)
816 Py_Exit(0);
817 if (PyInstance_Check(v)) {
818 /* we expect the error code to be store in the
819 `code' attribute
820 */
821 PyObject *code = PyObject_GetAttrString(v, "code");
822 if (code) {
823 Py_DECREF(v);
824 v = code;
825 if (v == Py_None)
826 Py_Exit(0);
827 }
828 /* if we failed to dig out the "code" attribute,
829 then just let the else clause below print the
830 error
831 */
832 }
833 if (PyInt_Check(v))
834 Py_Exit((int)PyInt_AsLong(v));
835 else {
836 /* OK to use real stderr here */
837 PyObject_Print(v, stderr, Py_PRINT_RAW);
838 fprintf(stderr, "\n");
839 Py_Exit(1);
840 }
841 } 842 }
842 if (set_sys_last_vars) { 843 if (set_sys_last_vars) {
843 PySys_SetObject("last_type", exception); 844 PySys_SetObject("last_type", exception);
844 PySys_SetObject("last_value", v); 845 PySys_SetObject("last_value", v);
845 PySys_SetObject("last_traceback", tb); 846 PySys_SetObject("last_traceback", tb);
851 PyObject *result = PyEval_CallObject(hook, args); 852 PyObject *result = PyEval_CallObject(hook, args);
852 if (result == NULL) { 853 if (result == NULL) {
853 PyObject *exception2, *v2, *tb2; 854 PyObject *exception2, *v2, *tb2;
854 PyErr_Fetch(&exception2, &v2, &tb2); 855 PyErr_Fetch(&exception2, &v2, &tb2);
855 PyErr_NormalizeException(&exception2, &v2, &tb2); 856 PyErr_NormalizeException(&exception2, &v2, &tb2);
857 if (PyErr_GivenExceptionMatches(
858 exception2, PyExc_SystemExit)) {
859 PyRun_HandleSystemExit(v2);
860 }
856 if (Py_FlushLine()) 861 if (Py_FlushLine())
857 PyErr_Clear(); 862 PyErr_Clear();
858 fflush(stdout); 863 fflush(stdout);
859 PySys_WriteStderr("Error in sys.excepthook:\n"); 864 PySys_WriteStderr("Error in sys.excepthook:\n");
860 PyErr_Display(exception2, v2, tb2); 865 PyErr_Display(exception2, v2, tb2);
1252 1257
1253 if (exitfunc) { 1258 if (exitfunc) {
1254 PyObject *res, *f; 1259 PyObject *res, *f;
1255 Py_INCREF(exitfunc); 1260 Py_INCREF(exitfunc);
1256 PySys_SetObject("exitfunc", (PyObject *)NULL); 1261 PySys_SetObject("exitfunc", (PyObject *)NULL);
1257 f = PySys_GetObject("stderr");
1258 res = PyEval_CallObject(exitfunc, (PyObject *)NULL); 1262 res = PyEval_CallObject(exitfunc, (PyObject *)NULL);
1259 if (res == NULL) { 1263 if (res == NULL) {
1260 if (f) 1264 if (!PyErr_ExceptionMatches(PyExc_SystemExit)) {
1261 PyFile_WriteString("Error in sys.exitfunc:\n", f); 1265 PySys_WriteStderr("Error in sys.exitfunc:\n");
1266 }
1262 PyErr_Print(); 1267 PyErr_Print();
1263 } 1268 }
1264 Py_DECREF(exitfunc); 1269 Py_DECREF(exitfunc);
1265 } 1270 }
1266 1271