Skip to content

Commit f893bb2

Browse files
iritkatrielErlend Egeberg Aasland
and
Erlend Egeberg Aasland
authored
bpo-45635: refactor print_exception() into smaller functions (GH-29981)
Co-authored-by: Erlend Egeberg Aasland <[email protected]>
1 parent d4363d2 commit f893bb2

File tree

1 file changed

+139
-87
lines changed

1 file changed

+139
-87
lines changed

Python/pythonrun.c

Lines changed: 139 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -908,38 +908,35 @@ write_indented_margin(struct exception_print_context *ctx, PyObject *f)
908908
return _Py_WriteIndentedMargin(EXC_INDENT(ctx), EXC_MARGIN(ctx), f);
909909
}
910910

911-
static void
912-
print_exception(struct exception_print_context *ctx, PyObject *value)
911+
static int
912+
print_exception_invalid_type(struct exception_print_context *ctx,
913+
PyObject *value)
913914
{
914-
int err = 0;
915-
PyObject *type, *tb, *tmp;
916915
PyObject *f = ctx->file;
917-
918-
_Py_IDENTIFIER(print_file_and_line);
919-
920-
if (!PyExceptionInstance_Check(value)) {
921-
if (err == 0) {
922-
err = _Py_WriteIndent(EXC_INDENT(ctx), f);
923-
}
924-
if (err == 0) {
925-
err = PyFile_WriteString("TypeError: print_exception(): Exception expected for value, ", f);
926-
}
927-
if (err == 0) {
928-
err = PyFile_WriteString(Py_TYPE(value)->tp_name, f);
929-
}
930-
if (err == 0) {
931-
err = PyFile_WriteString(" found\n", f);
932-
}
933-
if (err != 0) {
934-
PyErr_Clear();
935-
}
936-
return;
916+
if (_Py_WriteIndent(EXC_INDENT(ctx), f) < 0) {
917+
return -1;
918+
}
919+
const char *const msg = "TypeError: print_exception(): Exception expected "
920+
"for value, ";
921+
if (PyFile_WriteString(msg, f) < 0) {
922+
return -1;
923+
}
924+
if (PyFile_WriteString(Py_TYPE(value)->tp_name, f) < 0) {
925+
return -1;
926+
}
927+
if (PyFile_WriteString(" found\n", f) < 0) {
928+
return -1;
937929
}
930+
return 0;
931+
}
938932

939-
Py_INCREF(value);
940-
fflush(stdout);
941-
type = (PyObject *) Py_TYPE(value);
942-
tb = PyException_GetTraceback(value);
933+
static int
934+
print_exception_traceback(struct exception_print_context *ctx, PyObject *value)
935+
{
936+
PyObject *f = ctx->file;
937+
int err = 0;
938+
939+
PyObject *tb = PyException_GetTraceback(value);
943940
if (tb && tb != Py_None) {
944941
const char *header = EXCEPTION_TB_HEADER;
945942
const char *header_margin = EXC_MARGIN(ctx);
@@ -952,6 +949,117 @@ print_exception(struct exception_print_context *ctx, PyObject *value)
952949
err = _PyTraceBack_Print_Indented(
953950
tb, EXC_INDENT(ctx), EXC_MARGIN(ctx), header_margin, header, f);
954951
}
952+
Py_XDECREF(tb);
953+
return err;
954+
}
955+
956+
/* Prints the message line: module.qualname[: str(exc)] */
957+
static int
958+
print_exception_message(struct exception_print_context *ctx, PyObject *type,
959+
PyObject *value)
960+
{
961+
PyObject *f = ctx->file;
962+
963+
_Py_IDENTIFIER(__module__);
964+
965+
assert(PyExceptionClass_Check(type));
966+
967+
if (write_indented_margin(ctx, f) < 0) {
968+
return -1;
969+
}
970+
PyObject *modulename = _PyObject_GetAttrId(type, &PyId___module__);
971+
if (modulename == NULL || !PyUnicode_Check(modulename)) {
972+
Py_XDECREF(modulename);
973+
PyErr_Clear();
974+
if (PyFile_WriteString("<unknown>.", f) < 0) {
975+
return -1;
976+
}
977+
}
978+
else {
979+
if (!_PyUnicode_EqualToASCIIId(modulename, &PyId_builtins) &&
980+
!_PyUnicode_EqualToASCIIId(modulename, &PyId___main__))
981+
{
982+
int res = PyFile_WriteObject(modulename, f, Py_PRINT_RAW);
983+
Py_DECREF(modulename);
984+
if (res < 0) {
985+
return -1;
986+
}
987+
if (PyFile_WriteString(".", f) < 0) {
988+
return -1;
989+
}
990+
}
991+
else {
992+
Py_DECREF(modulename);
993+
}
994+
}
995+
996+
PyObject *qualname = PyType_GetQualName((PyTypeObject *)type);
997+
if (qualname == NULL || !PyUnicode_Check(qualname)) {
998+
Py_XDECREF(qualname);
999+
PyErr_Clear();
1000+
if (PyFile_WriteString("<unknown>", f) < 0) {
1001+
return -1;
1002+
}
1003+
}
1004+
else {
1005+
int res = PyFile_WriteObject(qualname, f, Py_PRINT_RAW);
1006+
Py_DECREF(qualname);
1007+
if (res < 0) {
1008+
return -1;
1009+
}
1010+
}
1011+
1012+
if (Py_IsNone(value)) {
1013+
return 0;
1014+
}
1015+
1016+
PyObject *s = PyObject_Str(value);
1017+
if (s == NULL) {
1018+
PyErr_Clear();
1019+
if (PyFile_WriteString(": <exception str() failed>", f) < 0) {
1020+
return -1;
1021+
}
1022+
}
1023+
else {
1024+
/* only print colon if the str() of the
1025+
object is not the empty string
1026+
*/
1027+
if (!PyUnicode_Check(s) || PyUnicode_GetLength(s) != 0) {
1028+
if (PyFile_WriteString(": ", f) < 0) {
1029+
Py_DECREF(s);
1030+
return -1;
1031+
}
1032+
}
1033+
int res = PyFile_WriteObject(s, f, Py_PRINT_RAW);
1034+
Py_DECREF(s);
1035+
if (res < 0) {
1036+
return -1;
1037+
}
1038+
}
1039+
1040+
return 0;
1041+
}
1042+
1043+
static void
1044+
print_exception(struct exception_print_context *ctx, PyObject *value)
1045+
{
1046+
int err = 0;
1047+
PyObject *tmp;
1048+
PyObject *f = ctx->file;
1049+
1050+
_Py_IDENTIFIER(print_file_and_line);
1051+
1052+
if (!PyExceptionInstance_Check(value)) {
1053+
if (print_exception_invalid_type(ctx, value) < 0) {
1054+
PyErr_Clear(); /* TODO: change to return -1 */
1055+
}
1056+
return;
1057+
}
1058+
1059+
Py_INCREF(value);
1060+
fflush(stdout);
1061+
PyObject *type = (PyObject *) Py_TYPE(value);
1062+
err = print_exception_traceback(ctx, value);
9551063
if (err == 0 &&
9561064
(err = _PyObject_LookupAttrId(value, &PyId_print_file_and_line, &tmp)) > 0)
9571065
{
@@ -1006,66 +1114,11 @@ print_exception(struct exception_print_context *ctx, PyObject *value)
10061114
err = -1;
10071115
}
10081116
}
1009-
if (err != 0) {
1010-
/* Don't do anything else */
1011-
}
1012-
else {
1013-
PyObject* modulename;
10141117

1015-
_Py_IDENTIFIER(__module__);
1016-
assert(PyExceptionClass_Check(type));
1017-
1018-
err = write_indented_margin(ctx, f);
1019-
if (err == 0) {
1020-
modulename = _PyObject_GetAttrId(type, &PyId___module__);
1021-
if (modulename == NULL || !PyUnicode_Check(modulename))
1022-
{
1023-
Py_XDECREF(modulename);
1024-
PyErr_Clear();
1025-
err = PyFile_WriteString("<unknown>.", f);
1026-
}
1027-
else {
1028-
if (!_PyUnicode_EqualToASCIIId(modulename, &PyId_builtins) &&
1029-
!_PyUnicode_EqualToASCIIId(modulename, &PyId___main__))
1030-
{
1031-
err = PyFile_WriteObject(modulename, f, Py_PRINT_RAW);
1032-
if (err == 0) {
1033-
err = PyFile_WriteString(".", f);
1034-
}
1035-
}
1036-
Py_DECREF(modulename);
1037-
}
1038-
}
1039-
if (err == 0) {
1040-
PyObject* qualname = PyType_GetQualName((PyTypeObject *)type);
1041-
if (qualname == NULL || !PyUnicode_Check(qualname)) {
1042-
Py_XDECREF(qualname);
1043-
PyErr_Clear();
1044-
err = PyFile_WriteString("<unknown>", f);
1045-
}
1046-
else {
1047-
err = PyFile_WriteObject(qualname, f, Py_PRINT_RAW);
1048-
Py_DECREF(qualname);
1049-
}
1050-
}
1051-
}
1052-
if (err == 0 && (value != Py_None)) {
1053-
PyObject *s = PyObject_Str(value);
1054-
/* only print colon if the str() of the
1055-
object is not the empty string
1056-
*/
1057-
if (s == NULL) {
1058-
PyErr_Clear();
1059-
err = -1;
1060-
PyFile_WriteString(": <exception str() failed>", f);
1061-
}
1062-
else if (!PyUnicode_Check(s) ||
1063-
PyUnicode_GetLength(s) != 0)
1064-
err = PyFile_WriteString(": ", f);
1065-
if (err == 0)
1066-
err = PyFile_WriteObject(s, f, Py_PRINT_RAW);
1067-
Py_XDECREF(s);
1118+
if (err == 0) {
1119+
err = print_exception_message(ctx, type, value);
10681120
}
1121+
10691122
/* try to write a newline in any case */
10701123
if (err < 0) {
10711124
PyErr_Clear();
@@ -1118,7 +1171,6 @@ print_exception(struct exception_print_context *ctx, PyObject *value)
11181171
}
11191172
Py_XDECREF(note);
11201173
}
1121-
Py_XDECREF(tb);
11221174
Py_DECREF(value);
11231175
/* If an error happened here, don't show it.
11241176
XXX This is wrong, but too many callers rely on this behavior. */

0 commit comments

Comments
 (0)