Skip to content

Commit d596acb

Browse files
iritkatrielErlend Egeberg Aasland
andauthored
bpo-45635: standardize error handling in traceback.c (pythonGH-29905)
Co-authored-by: Erlend Egeberg Aasland <[email protected]>
1 parent 8319114 commit d596acb

File tree

1 file changed

+104
-66
lines changed

1 file changed

+104
-66
lines changed

Python/traceback.c

Lines changed: 104 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -385,16 +385,14 @@ _Py_FindSourceFile(PyObject *filename, char* namebuf, size_t namelen, PyObject *
385385
int
386386
_Py_WriteIndent(int indent, PyObject *f)
387387
{
388-
int err = 0;
389388
char buf[11] = " ";
390389
assert(strlen(buf) == 10);
391390
while (indent > 0) {
392391
if (indent < 10) {
393392
buf[indent] = '\0';
394393
}
395-
err = PyFile_WriteString(buf, f);
396-
if (err != 0) {
397-
return err;
394+
if (PyFile_WriteString(buf, f) < 0) {
395+
return -1;
398396
}
399397
indent -= 10;
400398
}
@@ -407,19 +405,22 @@ _Py_WriteIndent(int indent, PyObject *f)
407405
int
408406
_Py_WriteIndentedMargin(int indent, const char *margin, PyObject *f)
409407
{
410-
int err = _Py_WriteIndent(indent, f);
411-
if (err == 0 && margin) {
412-
err = PyFile_WriteString(margin, f);
408+
if (_Py_WriteIndent(indent, f) < 0) {
409+
return -1;
413410
}
414-
return err;
411+
if (margin) {
412+
if (PyFile_WriteString(margin, f) < 0) {
413+
return -1;
414+
}
415+
}
416+
return 0;
415417
}
416418

417419
static int
418420
display_source_line_with_margin(PyObject *f, PyObject *filename, int lineno, int indent,
419421
int margin_indent, const char *margin,
420422
int *truncation, PyObject **line)
421423
{
422-
int err = 0;
423424
int fd;
424425
int i;
425426
char *found_encoding;
@@ -502,19 +503,20 @@ display_source_line_with_margin(PyObject *f, PyObject *filename, int lineno, int
502503
lineobj = PyFile_GetLine(fob, -1);
503504
if (!lineobj) {
504505
PyErr_Clear();
505-
err = -1;
506506
break;
507507
}
508508
}
509509
res = _PyObject_CallMethodIdNoArgs(fob, &PyId_close);
510-
if (res)
510+
if (res) {
511511
Py_DECREF(res);
512-
else
512+
}
513+
else {
513514
PyErr_Clear();
515+
}
514516
Py_DECREF(fob);
515517
if (!lineobj || !PyUnicode_Check(lineobj)) {
516518
Py_XDECREF(lineobj);
517-
return err;
519+
return -1;
518520
}
519521

520522
if (line) {
@@ -545,23 +547,29 @@ display_source_line_with_margin(PyObject *f, PyObject *filename, int lineno, int
545547
*truncation = i - indent;
546548
}
547549

548-
if (err == 0) {
549-
err = _Py_WriteIndentedMargin(margin_indent, margin, f);
550+
if (_Py_WriteIndentedMargin(margin_indent, margin, f) < 0) {
551+
goto error;
550552
}
553+
551554
/* Write some spaces before the line */
552-
if (err == 0) {
553-
err = _Py_WriteIndent(indent, f);
555+
if (_Py_WriteIndent(indent, f) < 0) {
556+
goto error;
554557
}
555558

556559
/* finally display the line */
557-
if (err == 0) {
558-
err = PyFile_WriteObject(lineobj, f, Py_PRINT_RAW);
560+
if (PyFile_WriteObject(lineobj, f, Py_PRINT_RAW) < 0) {
561+
goto error;
559562
}
560-
Py_DECREF(lineobj);
561-
if (err == 0) {
562-
err = PyFile_WriteString("\n", f);
563+
564+
if (PyFile_WriteString("\n", f) < 0) {
565+
goto error;
563566
}
564-
return err;
567+
568+
Py_DECREF(lineobj);
569+
return 0;
570+
error:
571+
Py_DECREF(lineobj);
572+
return -1;
565573
}
566574

567575
int
@@ -723,41 +731,51 @@ static inline int
723731
print_error_location_carets(PyObject *f, int offset, Py_ssize_t start_offset, Py_ssize_t end_offset,
724732
Py_ssize_t right_start_offset, Py_ssize_t left_end_offset,
725733
const char *primary, const char *secondary) {
726-
int err = 0;
727734
int special_chars = (left_end_offset != -1 || right_start_offset != -1);
735+
const char *str;
728736
while (++offset <= end_offset) {
729737
if (offset <= start_offset || offset > end_offset) {
730-
err = PyFile_WriteString(" ", f);
738+
str = " ";
731739
} else if (special_chars && left_end_offset < offset && offset <= right_start_offset) {
732-
err = PyFile_WriteString(secondary, f);
740+
str = secondary;
733741
} else {
734-
err = PyFile_WriteString(primary, f);
742+
str = primary;
743+
}
744+
if (PyFile_WriteString(str, f) < 0) {
745+
return -1;
735746
}
736747
}
737-
err = PyFile_WriteString("\n", f);
738-
return err;
748+
if (PyFile_WriteString("\n", f) < 0) {
749+
return -1;
750+
}
751+
return 0;
739752
}
740753

741754
static int
742755
tb_displayline(PyTracebackObject* tb, PyObject *f, PyObject *filename, int lineno,
743756
PyFrameObject *frame, PyObject *name, int margin_indent, const char *margin)
744757
{
745-
int err;
746-
PyObject *line;
758+
if (filename == NULL || name == NULL) {
759+
return -1;
760+
}
747761

748-
if (filename == NULL || name == NULL)
762+
if (_Py_WriteIndentedMargin(margin_indent, margin, f) < 0) {
749763
return -1;
750-
line = PyUnicode_FromFormat(" File \"%U\", line %d, in %U\n",
751-
filename, lineno, name);
752-
if (line == NULL)
764+
}
765+
766+
PyObject *line = PyUnicode_FromFormat(" File \"%U\", line %d, in %U\n",
767+
filename, lineno, name);
768+
if (line == NULL) {
753769
return -1;
754-
err = _Py_WriteIndentedMargin(margin_indent, margin, f);
755-
if (err == 0) {
756-
err = PyFile_WriteObject(line, f, Py_PRINT_RAW);
757770
}
771+
772+
int res = PyFile_WriteObject(line, f, Py_PRINT_RAW);
758773
Py_DECREF(line);
759-
if (err != 0)
760-
return err;
774+
if (res < 0) {
775+
return -1;
776+
}
777+
778+
int err = 0;
761779

762780
int truncation = _TRACEBACK_SOURCE_LINE_INDENT;
763781
PyObject* source_line = NULL;
@@ -849,11 +867,16 @@ tb_displayline(PyTracebackObject* tb, PyObject *f, PyObject *filename, int linen
849867
end_offset = i + 1;
850868
}
851869

852-
err = _Py_WriteIndentedMargin(margin_indent, margin, f);
853-
if (err == 0) {
854-
err = print_error_location_carets(f, truncation, start_offset, end_offset,
855-
right_start_offset, left_end_offset,
856-
primary_error_char, secondary_error_char);
870+
if (_Py_WriteIndentedMargin(margin_indent, margin, f) < 0) {
871+
err = -1;
872+
goto done;
873+
}
874+
875+
if (print_error_location_carets(f, truncation, start_offset, end_offset,
876+
right_start_offset, left_end_offset,
877+
primary_error_char, secondary_error_char) < 0) {
878+
err = -1;
879+
goto done;
857880
}
858881

859882
done:
@@ -884,7 +907,7 @@ static int
884907
tb_printinternal(PyTracebackObject *tb, PyObject *f, long limit,
885908
int indent, const char *margin)
886909
{
887-
int err = 0;
910+
PyCodeObject *code = NULL;
888911
Py_ssize_t depth = 0;
889912
PyObject *last_file = NULL;
890913
int last_line = -1;
@@ -899,35 +922,45 @@ tb_printinternal(PyTracebackObject *tb, PyObject *f, long limit,
899922
depth--;
900923
tb = tb->tb_next;
901924
}
902-
while (tb != NULL && err == 0) {
903-
PyCodeObject *code = PyFrame_GetCode(tb->tb_frame);
925+
while (tb != NULL) {
926+
code = PyFrame_GetCode(tb->tb_frame);
904927
if (last_file == NULL ||
905928
code->co_filename != last_file ||
906929
last_line == -1 || tb->tb_lineno != last_line ||
907930
last_name == NULL || code->co_name != last_name) {
908931
if (cnt > TB_RECURSIVE_CUTOFF) {
909-
err = tb_print_line_repeated(f, cnt);
932+
if (tb_print_line_repeated(f, cnt) < 0) {
933+
goto error;
934+
}
910935
}
911936
last_file = code->co_filename;
912937
last_line = tb->tb_lineno;
913938
last_name = code->co_name;
914939
cnt = 0;
915940
}
916941
cnt++;
917-
if (err == 0 && cnt <= TB_RECURSIVE_CUTOFF) {
918-
err = tb_displayline(tb, f, code->co_filename, tb->tb_lineno,
919-
tb->tb_frame, code->co_name, indent, margin);
920-
if (err == 0) {
921-
err = PyErr_CheckSignals();
942+
if (cnt <= TB_RECURSIVE_CUTOFF) {
943+
if (tb_displayline(tb, f, code->co_filename, tb->tb_lineno,
944+
tb->tb_frame, code->co_name, indent, margin) < 0) {
945+
goto error;
946+
}
947+
948+
if (PyErr_CheckSignals() < 0) {
949+
goto error;
922950
}
923951
}
924-
Py_DECREF(code);
952+
Py_CLEAR(code);
925953
tb = tb->tb_next;
926954
}
927-
if (err == 0 && cnt > TB_RECURSIVE_CUTOFF) {
928-
err = tb_print_line_repeated(f, cnt);
955+
if (cnt > TB_RECURSIVE_CUTOFF) {
956+
if (tb_print_line_repeated(f, cnt) < 0) {
957+
goto error;
958+
}
929959
}
930-
return err;
960+
return 0;
961+
error:
962+
Py_XDECREF(code);
963+
return -1;
931964
}
932965

933966
#define PyTraceBack_LIMIT 1000
@@ -936,12 +969,12 @@ int
936969
_PyTraceBack_Print_Indented(PyObject *v, int indent, const char *margin,
937970
const char *header_margin, const char *header, PyObject *f)
938971
{
939-
int err;
940972
PyObject *limitv;
941973
long limit = PyTraceBack_LIMIT;
942974

943-
if (v == NULL)
975+
if (v == NULL) {
944976
return 0;
977+
}
945978
if (!PyTraceBack_Check(v)) {
946979
PyErr_BadInternalCall();
947980
return -1;
@@ -957,14 +990,19 @@ _PyTraceBack_Print_Indented(PyObject *v, int indent, const char *margin,
957990
return 0;
958991
}
959992
}
960-
err = _Py_WriteIndentedMargin(indent, header_margin, f);
961-
if (err == 0) {
962-
err = PyFile_WriteString(header, f);
993+
if (_Py_WriteIndentedMargin(indent, header_margin, f) < 0) {
994+
return -1;
995+
}
996+
997+
if (PyFile_WriteString(header, f) < 0) {
998+
return -1;
963999
}
964-
if (err == 0) {
965-
err = tb_printinternal((PyTracebackObject *)v, f, limit, indent, margin);
1000+
1001+
if (tb_printinternal((PyTracebackObject *)v, f, limit, indent, margin) < 0) {
1002+
return -1;
9661003
}
967-
return err;
1004+
1005+
return 0;
9681006
}
9691007

9701008
int

0 commit comments

Comments
 (0)