@@ -940,90 +940,121 @@ PyErr_NewExceptionWithDoc(const char *name, const char *doc,
940
940
}
941
941
942
942
943
- /* Call when an exception has occurred but there is no way for Python
944
- to handle it. Examples: exception in __del__ or during GC. */
945
- void
946
- PyErr_WriteUnraisable (PyObject * obj )
943
+ static void
944
+ write_unraisable_exc_file (PyObject * exc_type , PyObject * exc_value ,
945
+ PyObject * exc_tb , PyObject * obj , PyObject * file )
947
946
{
948
- _Py_IDENTIFIER (__module__ );
949
- PyObject * f , * t , * v , * tb ;
950
- PyObject * moduleName = NULL ;
951
- char * className ;
952
-
953
- PyErr_Fetch (& t , & v , & tb );
954
-
955
- f = _PySys_GetObjectId (& PyId_stderr );
956
- if (f == NULL || f == Py_None )
957
- goto done ;
958
-
959
947
if (obj ) {
960
- if (PyFile_WriteString ("Exception ignored in: " , f ) < 0 )
961
- goto done ;
962
- if (PyFile_WriteObject (obj , f , 0 ) < 0 ) {
948
+ if (PyFile_WriteString ("Exception ignored in: " , file ) < 0 ) {
949
+ return ;
950
+ }
951
+ if (PyFile_WriteObject (obj , file , 0 ) < 0 ) {
963
952
PyErr_Clear ();
964
- if (PyFile_WriteString ("<object repr() failed>" , f ) < 0 ) {
965
- goto done ;
953
+ if (PyFile_WriteString ("<object repr() failed>" , file ) < 0 ) {
954
+ return ;
966
955
}
967
956
}
968
- if (PyFile_WriteString ("\n" , f ) < 0 )
969
- goto done ;
957
+ if (PyFile_WriteString ("\n" , file ) < 0 ) {
958
+ return ;
959
+ }
970
960
}
971
961
972
- if (PyTraceBack_Print (tb , f ) < 0 )
973
- goto done ;
962
+ if (exc_tb != NULL ) {
963
+ if (PyTraceBack_Print (exc_tb , file ) < 0 ) {
964
+ /* continue even if writing the traceback failed */
965
+ PyErr_Clear ();
966
+ }
967
+ }
974
968
975
- if (!t )
976
- goto done ;
969
+ if (!exc_type ) {
970
+ return ;
971
+ }
977
972
978
- assert (PyExceptionClass_Check (t ));
979
- className = PyExceptionClass_Name (t );
973
+ assert (PyExceptionClass_Check (exc_type ));
974
+ char * className = PyExceptionClass_Name (exc_type );
980
975
if (className != NULL ) {
981
976
char * dot = strrchr (className , '.' );
982
- if (dot != NULL )
977
+ if (dot != NULL ) {
983
978
className = dot + 1 ;
979
+ }
984
980
}
985
981
986
- moduleName = _PyObject_GetAttrId (t , & PyId___module__ );
982
+ _Py_IDENTIFIER (__module__ );
983
+ PyObject * moduleName = _PyObject_GetAttrId (exc_type , & PyId___module__ );
987
984
if (moduleName == NULL || !PyUnicode_Check (moduleName )) {
985
+ Py_XDECREF (moduleName );
988
986
PyErr_Clear ();
989
- if (PyFile_WriteString ("<unknown>" , f ) < 0 )
990
- goto done ;
987
+ if (PyFile_WriteString ("<unknown>" , file ) < 0 ) {
988
+ return ;
989
+ }
991
990
}
992
991
else {
993
992
if (!_PyUnicode_EqualToASCIIId (moduleName , & PyId_builtins )) {
994
- if (PyFile_WriteObject (moduleName , f , Py_PRINT_RAW ) < 0 )
995
- goto done ;
996
- if (PyFile_WriteString ("." , f ) < 0 )
997
- goto done ;
993
+ if (PyFile_WriteObject (moduleName , file , Py_PRINT_RAW ) < 0 ) {
994
+ Py_DECREF (moduleName );
995
+ return ;
996
+ }
997
+ Py_DECREF (moduleName );
998
+ if (PyFile_WriteString ("." , file ) < 0 ) {
999
+ return ;
1000
+ }
1001
+ }
1002
+ else {
1003
+ Py_DECREF (moduleName );
998
1004
}
999
1005
}
1006
+
1000
1007
if (className == NULL ) {
1001
- if (PyFile_WriteString ("<unknown>" , f ) < 0 )
1002
- goto done ;
1008
+ if (PyFile_WriteString ("<unknown>" , file ) < 0 ) {
1009
+ return ;
1010
+ }
1003
1011
}
1004
1012
else {
1005
- if (PyFile_WriteString (className , f ) < 0 )
1006
- goto done ;
1013
+ if (PyFile_WriteString (className , file ) < 0 ) {
1014
+ return ;
1015
+ }
1007
1016
}
1008
1017
1009
- if (v && v != Py_None ) {
1010
- if (PyFile_WriteString (": " , f ) < 0 )
1011
- goto done ;
1012
- if (PyFile_WriteObject (v , f , Py_PRINT_RAW ) < 0 ) {
1018
+ if (exc_value && exc_value != Py_None ) {
1019
+ if (PyFile_WriteString (": " , file ) < 0 ) {
1020
+ return ;
1021
+ }
1022
+ if (PyFile_WriteObject (exc_value , file , Py_PRINT_RAW ) < 0 ) {
1013
1023
PyErr_Clear ();
1014
- if (PyFile_WriteString ("<exception str() failed>" , f ) < 0 ) {
1015
- goto done ;
1024
+ if (PyFile_WriteString ("<exception str() failed>" , file ) < 0 ) {
1025
+ return ;
1016
1026
}
1017
1027
}
1018
1028
}
1019
- if (PyFile_WriteString ("\n" , f ) < 0 )
1020
- goto done ;
1029
+ if (PyFile_WriteString ("\n" , file ) < 0 ) {
1030
+ return ;
1031
+ }
1032
+ }
1021
1033
1022
- done :
1023
- Py_XDECREF (moduleName );
1024
- Py_XDECREF (t );
1025
- Py_XDECREF (v );
1026
- Py_XDECREF (tb );
1034
+
1035
+ /* Display an unraisable exception into sys.stderr.
1036
+
1037
+ Called when an exception has occurred but there is no way for Python to
1038
+ handle it. For example, when a destructor raises an exception or during
1039
+ garbage collection (gc.collect()).
1040
+
1041
+ An exception must be set when calling this function. */
1042
+ void
1043
+ PyErr_WriteUnraisable (PyObject * obj )
1044
+ {
1045
+ PyObject * f , * exc_type , * exc_value , * exc_tb ;
1046
+
1047
+ PyErr_Fetch (& exc_type , & exc_value , & exc_tb );
1048
+
1049
+ f = _PySys_GetObjectId (& PyId_stderr );
1050
+ /* Do nothing if sys.stderr is not available or set to None */
1051
+ if (f != NULL && f != Py_None ) {
1052
+ write_unraisable_exc_file (exc_type , exc_value , exc_tb , obj , f );
1053
+ }
1054
+
1055
+ Py_XDECREF (exc_type );
1056
+ Py_XDECREF (exc_value );
1057
+ Py_XDECREF (exc_tb );
1027
1058
PyErr_Clear (); /* Just in case */
1028
1059
}
1029
1060
0 commit comments