comparison Python/errors.c @ 85415:e63f19d0a651

Issue #18664, #18408: Rewrite PyErr_WriteUnraisable() to handle errors * Catch PyFile_WriteString() and PyFile_WriteObject() errors * Clear the current exception on _PyObject_GetAttrId() failure * Use PyUnicode_CompareWithASCIIString() and PyFile_WriteObject() instead of _PyUnicode_AsString() and strcmp() to avoid Unicode encoding error. stderr has a more tolerant error handler than utf-8/strict.
author Victor Stinner <vstinner@wyplay.com>
date Mon, 26 Aug 2013 14:04:10 +0200
parents 9b77b3ee6fb8
children df2fdd42b375
comparison
equal deleted inserted replaced
85414:79ce25c70795 85415:e63f19d0a651
823 void 823 void
824 PyErr_WriteUnraisable(PyObject *obj) 824 PyErr_WriteUnraisable(PyObject *obj)
825 { 825 {
826 _Py_IDENTIFIER(__module__); 826 _Py_IDENTIFIER(__module__);
827 PyObject *f, *t, *v, *tb; 827 PyObject *f, *t, *v, *tb;
828 PyObject *moduleName = NULL;
829 char* className;
830
828 PyErr_Fetch(&t, &v, &tb); 831 PyErr_Fetch(&t, &v, &tb);
832
829 f = PySys_GetObject("stderr"); 833 f = PySys_GetObject("stderr");
830 if (f != NULL && f != Py_None) { 834 if (f == NULL || f == Py_None)
831 if (obj) { 835 goto done;
832 PyFile_WriteString("Exception ignored in: ", f); 836
833 PyFile_WriteObject(obj, f, 0); 837 if (obj) {
834 PyFile_WriteString("\n", f); 838 if (PyFile_WriteString("Exception ignored in: ", f) < 0)
835 } 839 goto done;
836 PyTraceBack_Print(tb, f); 840 if (PyFile_WriteObject(obj, f, 0) < 0)
837 if (t) { 841 goto done;
838 PyObject* moduleName; 842 if (PyFile_WriteString("\n", f) < 0)
839 char* className; 843 goto done;
840 assert(PyExceptionClass_Check(t)); 844 }
841 className = PyExceptionClass_Name(t); 845
842 if (className != NULL) { 846 if (PyTraceBack_Print(tb, f) < 0)
843 char *dot = strrchr(className, '.'); 847 goto done;
844 if (dot != NULL) 848
845 className = dot+1; 849 if (!t)
846 } 850 goto done;
847 851
848 moduleName = _PyObject_GetAttrId(t, &PyId___module__); 852 assert(PyExceptionClass_Check(t));
849 if (moduleName == NULL) 853 className = PyExceptionClass_Name(t);
850 PyFile_WriteString("<unknown>", f); 854 if (className != NULL) {
851 else { 855 char *dot = strrchr(className, '.');
852 char* modstr = _PyUnicode_AsString(moduleName); 856 if (dot != NULL)
853 if (modstr && 857 className = dot+1;
854 strcmp(modstr, "builtins") != 0) 858 }
855 { 859
856 PyFile_WriteString(modstr, f); 860 moduleName = _PyObject_GetAttrId(t, &PyId___module__);
857 PyFile_WriteString(".", f); 861 if (moduleName == NULL) {
858 } 862 PyErr_Clear();
859 } 863 if (PyFile_WriteString("<unknown>", f) < 0)
860 if (className == NULL) 864 goto done;
861 PyFile_WriteString("<unknown>", f); 865 }
862 else 866 else {
863 PyFile_WriteString(className, f); 867 if (PyUnicode_CompareWithASCIIString(moduleName, "builtins") != 0) {
864 if (v && v != Py_None) { 868 if (PyFile_WriteObject(moduleName, f, Py_PRINT_RAW) < 0)
865 PyFile_WriteString(": ", f); 869 goto done;
866 PyFile_WriteObject(v, f, Py_PRINT_RAW); 870 if (PyFile_WriteString(".", f) < 0)
867 } 871 goto done;
868 PyFile_WriteString("\n", f); 872 }
869 Py_XDECREF(moduleName); 873 }
870 } 874 if (className == NULL) {
871 PyErr_Clear(); /* Just in case */ 875 if (PyFile_WriteString("<unknown>", f) < 0)
872 } 876 goto done;
877 }
878 else {
879 if (PyFile_WriteString(className, f) < 0)
880 goto done;
881 }
882
883 if (v && v != Py_None) {
884 if (PyFile_WriteString(": ", f) < 0)
885 goto done;
886 if (PyFile_WriteObject(v, f, Py_PRINT_RAW) < 0)
887 goto done;
888 }
889 if (PyFile_WriteString("\n", f) < 0)
890 goto done;
891
892 done:
893 Py_XDECREF(moduleName);
873 Py_XDECREF(t); 894 Py_XDECREF(t);
874 Py_XDECREF(v); 895 Py_XDECREF(v);
875 Py_XDECREF(tb); 896 Py_XDECREF(tb);
897 PyErr_Clear(); /* Just in case */
876 } 898 }
877 899
878 extern PyObject *PyModule_GetWarningsModule(void); 900 extern PyObject *PyModule_GetWarningsModule(void);
879 901
880 902