@@ -1040,6 +1040,78 @@ print_exception_message(struct exception_print_context *ctx, PyObject *type,
10401040 return 0 ;
10411041}
10421042
1043+ static int
1044+ print_exception_suggestions (struct exception_print_context * ctx ,
1045+ PyObject * value )
1046+ {
1047+ PyObject * f = ctx -> file ;
1048+ PyObject * suggestions = _Py_Offer_Suggestions (value );
1049+ if (suggestions ) {
1050+ // Add a trailer ". Did you mean: (...)?"
1051+ if (PyFile_WriteString (". Did you mean: '" , f ) < 0 ) {
1052+ goto error ;
1053+ }
1054+ if (PyFile_WriteObject (suggestions , f , Py_PRINT_RAW ) < 0 ) {
1055+ goto error ;
1056+ }
1057+ if (PyFile_WriteString ("'?" , f ) < 0 ) {
1058+ goto error ;
1059+ }
1060+ Py_DECREF (suggestions );
1061+ }
1062+ else if (PyErr_Occurred ()) {
1063+ PyErr_Clear ();
1064+ }
1065+ return 0 ;
1066+ error :
1067+ Py_XDECREF (suggestions );
1068+ return -1 ;
1069+ }
1070+
1071+ static int
1072+ print_exception_note (struct exception_print_context * ctx , PyObject * value )
1073+ {
1074+ PyObject * f = ctx -> file ;
1075+ _Py_IDENTIFIER (__note__ );
1076+
1077+ PyObject * note = _PyObject_GetAttrId (value , & PyId___note__ );
1078+ if (note == NULL ) {
1079+ return -1 ;
1080+ }
1081+ if (!PyUnicode_Check (note )) {
1082+ Py_DECREF (note );
1083+ return 0 ;
1084+ }
1085+
1086+ PyObject * lines = PyUnicode_Splitlines (note , 1 );
1087+ Py_DECREF (note );
1088+
1089+ if (lines == NULL ) {
1090+ return -1 ;
1091+ }
1092+
1093+ Py_ssize_t n = PyList_GET_SIZE (lines );
1094+ for (Py_ssize_t i = 0 ; i < n ; i ++ ) {
1095+ PyObject * line = PyList_GET_ITEM (lines , i );
1096+ assert (PyUnicode_Check (line ));
1097+ if (write_indented_margin (ctx , f ) < 0 ) {
1098+ goto error ;
1099+ }
1100+ if (PyFile_WriteObject (line , f , Py_PRINT_RAW ) < 0 ) {
1101+ goto error ;
1102+ }
1103+ }
1104+ if (PyFile_WriteString ("\n" , f ) < 0 ) {
1105+ goto error ;
1106+ }
1107+
1108+ Py_DECREF (lines );
1109+ return 0 ;
1110+ error :
1111+ Py_DECREF (lines );
1112+ return -1 ;
1113+ }
1114+
10431115static void
10441116print_exception (struct exception_print_context * ctx , PyObject * value )
10451117{
@@ -1073,13 +1145,12 @@ print_exception(struct exception_print_context *ctx, PyObject *value)
10731145 PyErr_Clear ();
10741146 }
10751147 else {
1076- PyObject * line ;
10771148
10781149 Py_DECREF (value );
10791150 value = message ;
10801151
1081- line = PyUnicode_FromFormat (" File \"%S\", line %zd\n" ,
1082- filename , lineno );
1152+ PyObject * line = PyUnicode_FromFormat (" File \"%S\", line %zd\n" ,
1153+ filename , lineno );
10831154 Py_DECREF (filename );
10841155 if (line != NULL ) {
10851156 err = write_indented_margin (ctx , f );
@@ -1118,59 +1189,16 @@ print_exception(struct exception_print_context *ctx, PyObject *value)
11181189 if (err == 0 ) {
11191190 err = print_exception_message (ctx , type , value );
11201191 }
1121-
1122- /* try to write a newline in any case */
1123- if (err < 0 ) {
1124- PyErr_Clear ();
1192+ if (err == 0 ) {
1193+ err = print_exception_suggestions (ctx , value );
11251194 }
1126- PyObject * suggestions = _Py_Offer_Suggestions (value );
1127- if (suggestions ) {
1128- // Add a trailer ". Did you mean: (...)?"
1129- err = PyFile_WriteString (". Did you mean: '" , f );
1130- if (err == 0 ) {
1131- err = PyFile_WriteObject (suggestions , f , Py_PRINT_RAW );
1132- err += PyFile_WriteString ("'?" , f );
1133- }
1134- Py_DECREF (suggestions );
1135- } else if (PyErr_Occurred ()) {
1136- PyErr_Clear ();
1195+ if (err == 0 ) {
1196+ err = PyFile_WriteString ("\n" , f );
11371197 }
1138- err += PyFile_WriteString ("\n" , f );
1139-
11401198 if (err == 0 && PyExceptionInstance_Check (value )) {
1141- _Py_IDENTIFIER (__note__ );
1142-
1143- PyObject * note = _PyObject_GetAttrId (value , & PyId___note__ );
1144- if (note == NULL ) {
1145- err = -1 ;
1146- }
1147- if (err == 0 && PyUnicode_Check (note )) {
1148- _Py_static_string (PyId_newline , "\n" );
1149- PyObject * lines = PyUnicode_Split (
1150- note , _PyUnicode_FromId (& PyId_newline ), -1 );
1151- if (lines == NULL ) {
1152- err = -1 ;
1153- }
1154- else {
1155- Py_ssize_t n = PyList_GET_SIZE (lines );
1156- for (Py_ssize_t i = 0 ; i < n ; i ++ ) {
1157- if (err == 0 ) {
1158- PyObject * line = PyList_GET_ITEM (lines , i );
1159- assert (PyUnicode_Check (line ));
1160- err = write_indented_margin (ctx , f );
1161- if (err == 0 ) {
1162- err = PyFile_WriteObject (line , f , Py_PRINT_RAW );
1163- }
1164- if (err == 0 ) {
1165- err = PyFile_WriteString ("\n" , f );
1166- }
1167- }
1168- }
1169- }
1170- Py_DECREF (lines );
1171- }
1172- Py_XDECREF (note );
1199+ err = print_exception_note (ctx , value );
11731200 }
1201+
11741202 Py_DECREF (value );
11751203 /* If an error happened here, don't show it.
11761204 XXX This is wrong, but too many callers rely on this behavior. */
@@ -1194,36 +1222,35 @@ print_chained(struct exception_print_context* ctx, PyObject *value,
11941222 const char * message , const char * tag )
11951223{
11961224 PyObject * f = ctx -> file ;
1197- bool need_close = ctx -> need_close ;
1198-
1199- int err = Py_EnterRecursiveCall (" in print_chained" );
1200- if (err == 0 ) {
1201- print_exception_recursive (ctx , value );
1202- Py_LeaveRecursiveCall ();
12031225
1204- if (err == 0 ) {
1205- err = write_indented_margin (ctx , f );
1206- }
1207- if (err == 0 ) {
1208- err = PyFile_WriteString ("\n" , f );
1209- }
1210- if (err == 0 ) {
1211- err = write_indented_margin (ctx , f );
1212- }
1213- if (err == 0 ) {
1214- err = PyFile_WriteString (message , f );
1215- }
1216- if (err == 0 ) {
1217- err = write_indented_margin (ctx , f );
1218- }
1219- if (err == 0 ) {
1220- err = PyFile_WriteString ("\n" , f );
1221- }
1226+ if (Py_EnterRecursiveCall (" in print_chained" ) < 0 ) {
1227+ return -1 ;
12221228 }
1223-
1229+ bool need_close = ctx -> need_close ;
1230+ print_exception_recursive (ctx , value );
12241231 ctx -> need_close = need_close ;
12251232
1226- return err ;
1233+ Py_LeaveRecursiveCall ();
1234+
1235+ if (write_indented_margin (ctx , f ) < 0 ) {
1236+ return -1 ;
1237+ }
1238+ if (PyFile_WriteString ("\n" , f ) < 0 ) {
1239+ return -1 ;
1240+ }
1241+ if (write_indented_margin (ctx , f ) < 0 ) {
1242+ return -1 ;
1243+ }
1244+ if (PyFile_WriteString (message , f ) < 0 ) {
1245+ return -1 ;
1246+ }
1247+ if (write_indented_margin (ctx , f ) < 0 ) {
1248+ return -1 ;
1249+ }
1250+ if (PyFile_WriteString ("\n" , f ) < 0 ) {
1251+ return -1 ;
1252+ }
1253+ return 0 ;
12271254}
12281255
12291256static void
0 commit comments