@@ -940,90 +940,121 @@ PyErr_NewExceptionWithDoc(const char *name, const char *doc,
940940}
941941
942942
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 )
947946{
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-
959947 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 ) {
963952 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 ;
966955 }
967956 }
968- if (PyFile_WriteString ("\n" , f ) < 0 )
969- goto done ;
957+ if (PyFile_WriteString ("\n" , file ) < 0 ) {
958+ return ;
959+ }
970960 }
971961
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+ }
974968
975- if (!t )
976- goto done ;
969+ if (!exc_type ) {
970+ return ;
971+ }
977972
978- assert (PyExceptionClass_Check (t ));
979- className = PyExceptionClass_Name (t );
973+ assert (PyExceptionClass_Check (exc_type ));
974+ char * className = PyExceptionClass_Name (exc_type );
980975 if (className != NULL ) {
981976 char * dot = strrchr (className , '.' );
982- if (dot != NULL )
977+ if (dot != NULL ) {
983978 className = dot + 1 ;
979+ }
984980 }
985981
986- moduleName = _PyObject_GetAttrId (t , & PyId___module__ );
982+ _Py_IDENTIFIER (__module__ );
983+ PyObject * moduleName = _PyObject_GetAttrId (exc_type , & PyId___module__ );
987984 if (moduleName == NULL || !PyUnicode_Check (moduleName )) {
985+ Py_XDECREF (moduleName );
988986 PyErr_Clear ();
989- if (PyFile_WriteString ("<unknown>" , f ) < 0 )
990- goto done ;
987+ if (PyFile_WriteString ("<unknown>" , file ) < 0 ) {
988+ return ;
989+ }
991990 }
992991 else {
993992 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 );
9981004 }
9991005 }
1006+
10001007 if (className == NULL ) {
1001- if (PyFile_WriteString ("<unknown>" , f ) < 0 )
1002- goto done ;
1008+ if (PyFile_WriteString ("<unknown>" , file ) < 0 ) {
1009+ return ;
1010+ }
10031011 }
10041012 else {
1005- if (PyFile_WriteString (className , f ) < 0 )
1006- goto done ;
1013+ if (PyFile_WriteString (className , file ) < 0 ) {
1014+ return ;
1015+ }
10071016 }
10081017
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 ) {
10131023 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 ;
10161026 }
10171027 }
10181028 }
1019- if (PyFile_WriteString ("\n" , f ) < 0 )
1020- goto done ;
1029+ if (PyFile_WriteString ("\n" , file ) < 0 ) {
1030+ return ;
1031+ }
1032+ }
10211033
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 );
10271058 PyErr_Clear (); /* Just in case */
10281059}
10291060
0 commit comments