mirror of
https://github.com/python/cpython.git
synced 2025-09-26 10:19:53 +00:00
bpo-45635: standardize error handling in traceback.c (GH-29905)
Co-authored-by: Erlend Egeberg Aasland <erlend.aasland@innova.no>
This commit is contained in:
parent
8319114fee
commit
d596acbd3b
1 changed files with 106 additions and 68 deletions
|
@ -385,16 +385,14 @@ finally:
|
||||||
int
|
int
|
||||||
_Py_WriteIndent(int indent, PyObject *f)
|
_Py_WriteIndent(int indent, PyObject *f)
|
||||||
{
|
{
|
||||||
int err = 0;
|
|
||||||
char buf[11] = " ";
|
char buf[11] = " ";
|
||||||
assert(strlen(buf) == 10);
|
assert(strlen(buf) == 10);
|
||||||
while (indent > 0) {
|
while (indent > 0) {
|
||||||
if (indent < 10) {
|
if (indent < 10) {
|
||||||
buf[indent] = '\0';
|
buf[indent] = '\0';
|
||||||
}
|
}
|
||||||
err = PyFile_WriteString(buf, f);
|
if (PyFile_WriteString(buf, f) < 0) {
|
||||||
if (err != 0) {
|
return -1;
|
||||||
return err;
|
|
||||||
}
|
}
|
||||||
indent -= 10;
|
indent -= 10;
|
||||||
}
|
}
|
||||||
|
@ -407,11 +405,15 @@ _Py_WriteIndent(int indent, PyObject *f)
|
||||||
int
|
int
|
||||||
_Py_WriteIndentedMargin(int indent, const char *margin, PyObject *f)
|
_Py_WriteIndentedMargin(int indent, const char *margin, PyObject *f)
|
||||||
{
|
{
|
||||||
int err = _Py_WriteIndent(indent, f);
|
if (_Py_WriteIndent(indent, f) < 0) {
|
||||||
if (err == 0 && margin) {
|
return -1;
|
||||||
err = PyFile_WriteString(margin, f);
|
|
||||||
}
|
}
|
||||||
return err;
|
if (margin) {
|
||||||
|
if (PyFile_WriteString(margin, f) < 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
@ -419,7 +421,6 @@ display_source_line_with_margin(PyObject *f, PyObject *filename, int lineno, int
|
||||||
int margin_indent, const char *margin,
|
int margin_indent, const char *margin,
|
||||||
int *truncation, PyObject **line)
|
int *truncation, PyObject **line)
|
||||||
{
|
{
|
||||||
int err = 0;
|
|
||||||
int fd;
|
int fd;
|
||||||
int i;
|
int i;
|
||||||
char *found_encoding;
|
char *found_encoding;
|
||||||
|
@ -502,19 +503,20 @@ display_source_line_with_margin(PyObject *f, PyObject *filename, int lineno, int
|
||||||
lineobj = PyFile_GetLine(fob, -1);
|
lineobj = PyFile_GetLine(fob, -1);
|
||||||
if (!lineobj) {
|
if (!lineobj) {
|
||||||
PyErr_Clear();
|
PyErr_Clear();
|
||||||
err = -1;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
res = _PyObject_CallMethodIdNoArgs(fob, &PyId_close);
|
res = _PyObject_CallMethodIdNoArgs(fob, &PyId_close);
|
||||||
if (res)
|
if (res) {
|
||||||
Py_DECREF(res);
|
Py_DECREF(res);
|
||||||
else
|
}
|
||||||
|
else {
|
||||||
PyErr_Clear();
|
PyErr_Clear();
|
||||||
|
}
|
||||||
Py_DECREF(fob);
|
Py_DECREF(fob);
|
||||||
if (!lineobj || !PyUnicode_Check(lineobj)) {
|
if (!lineobj || !PyUnicode_Check(lineobj)) {
|
||||||
Py_XDECREF(lineobj);
|
Py_XDECREF(lineobj);
|
||||||
return err;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (line) {
|
if (line) {
|
||||||
|
@ -545,23 +547,29 @@ display_source_line_with_margin(PyObject *f, PyObject *filename, int lineno, int
|
||||||
*truncation = i - indent;
|
*truncation = i - indent;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (err == 0) {
|
if (_Py_WriteIndentedMargin(margin_indent, margin, f) < 0) {
|
||||||
err = _Py_WriteIndentedMargin(margin_indent, margin, f);
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Write some spaces before the line */
|
/* Write some spaces before the line */
|
||||||
if (err == 0) {
|
if (_Py_WriteIndent(indent, f) < 0) {
|
||||||
err = _Py_WriteIndent(indent, f);
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* finally display the line */
|
/* finally display the line */
|
||||||
if (err == 0) {
|
if (PyFile_WriteObject(lineobj, f, Py_PRINT_RAW) < 0) {
|
||||||
err = PyFile_WriteObject(lineobj, f, Py_PRINT_RAW);
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (PyFile_WriteString("\n", f) < 0) {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
Py_DECREF(lineobj);
|
Py_DECREF(lineobj);
|
||||||
if (err == 0) {
|
return 0;
|
||||||
err = PyFile_WriteString("\n", f);
|
error:
|
||||||
}
|
Py_DECREF(lineobj);
|
||||||
return err;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
@ -723,41 +731,51 @@ static inline int
|
||||||
print_error_location_carets(PyObject *f, int offset, Py_ssize_t start_offset, Py_ssize_t end_offset,
|
print_error_location_carets(PyObject *f, int offset, Py_ssize_t start_offset, Py_ssize_t end_offset,
|
||||||
Py_ssize_t right_start_offset, Py_ssize_t left_end_offset,
|
Py_ssize_t right_start_offset, Py_ssize_t left_end_offset,
|
||||||
const char *primary, const char *secondary) {
|
const char *primary, const char *secondary) {
|
||||||
int err = 0;
|
|
||||||
int special_chars = (left_end_offset != -1 || right_start_offset != -1);
|
int special_chars = (left_end_offset != -1 || right_start_offset != -1);
|
||||||
|
const char *str;
|
||||||
while (++offset <= end_offset) {
|
while (++offset <= end_offset) {
|
||||||
if (offset <= start_offset || offset > end_offset) {
|
if (offset <= start_offset || offset > end_offset) {
|
||||||
err = PyFile_WriteString(" ", f);
|
str = " ";
|
||||||
} else if (special_chars && left_end_offset < offset && offset <= right_start_offset) {
|
} else if (special_chars && left_end_offset < offset && offset <= right_start_offset) {
|
||||||
err = PyFile_WriteString(secondary, f);
|
str = secondary;
|
||||||
} else {
|
} else {
|
||||||
err = PyFile_WriteString(primary, f);
|
str = primary;
|
||||||
|
}
|
||||||
|
if (PyFile_WriteString(str, f) < 0) {
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
err = PyFile_WriteString("\n", f);
|
if (PyFile_WriteString("\n", f) < 0) {
|
||||||
return err;
|
return -1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
tb_displayline(PyTracebackObject* tb, PyObject *f, PyObject *filename, int lineno,
|
tb_displayline(PyTracebackObject* tb, PyObject *f, PyObject *filename, int lineno,
|
||||||
PyFrameObject *frame, PyObject *name, int margin_indent, const char *margin)
|
PyFrameObject *frame, PyObject *name, int margin_indent, const char *margin)
|
||||||
{
|
{
|
||||||
int err;
|
if (filename == NULL || name == NULL) {
|
||||||
PyObject *line;
|
|
||||||
|
|
||||||
if (filename == NULL || name == NULL)
|
|
||||||
return -1;
|
return -1;
|
||||||
line = PyUnicode_FromFormat(" File \"%U\", line %d, in %U\n",
|
|
||||||
filename, lineno, name);
|
|
||||||
if (line == NULL)
|
|
||||||
return -1;
|
|
||||||
err = _Py_WriteIndentedMargin(margin_indent, margin, f);
|
|
||||||
if (err == 0) {
|
|
||||||
err = PyFile_WriteObject(line, f, Py_PRINT_RAW);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (_Py_WriteIndentedMargin(margin_indent, margin, f) < 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
PyObject *line = PyUnicode_FromFormat(" File \"%U\", line %d, in %U\n",
|
||||||
|
filename, lineno, name);
|
||||||
|
if (line == NULL) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int res = PyFile_WriteObject(line, f, Py_PRINT_RAW);
|
||||||
Py_DECREF(line);
|
Py_DECREF(line);
|
||||||
if (err != 0)
|
if (res < 0) {
|
||||||
return err;
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int err = 0;
|
||||||
|
|
||||||
int truncation = _TRACEBACK_SOURCE_LINE_INDENT;
|
int truncation = _TRACEBACK_SOURCE_LINE_INDENT;
|
||||||
PyObject* source_line = NULL;
|
PyObject* source_line = NULL;
|
||||||
|
@ -849,11 +867,16 @@ tb_displayline(PyTracebackObject* tb, PyObject *f, PyObject *filename, int linen
|
||||||
end_offset = i + 1;
|
end_offset = i + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
err = _Py_WriteIndentedMargin(margin_indent, margin, f);
|
if (_Py_WriteIndentedMargin(margin_indent, margin, f) < 0) {
|
||||||
if (err == 0) {
|
err = -1;
|
||||||
err = print_error_location_carets(f, truncation, start_offset, end_offset,
|
goto done;
|
||||||
right_start_offset, left_end_offset,
|
}
|
||||||
primary_error_char, secondary_error_char);
|
|
||||||
|
if (print_error_location_carets(f, truncation, start_offset, end_offset,
|
||||||
|
right_start_offset, left_end_offset,
|
||||||
|
primary_error_char, secondary_error_char) < 0) {
|
||||||
|
err = -1;
|
||||||
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
done:
|
done:
|
||||||
|
@ -884,7 +907,7 @@ static int
|
||||||
tb_printinternal(PyTracebackObject *tb, PyObject *f, long limit,
|
tb_printinternal(PyTracebackObject *tb, PyObject *f, long limit,
|
||||||
int indent, const char *margin)
|
int indent, const char *margin)
|
||||||
{
|
{
|
||||||
int err = 0;
|
PyCodeObject *code = NULL;
|
||||||
Py_ssize_t depth = 0;
|
Py_ssize_t depth = 0;
|
||||||
PyObject *last_file = NULL;
|
PyObject *last_file = NULL;
|
||||||
int last_line = -1;
|
int last_line = -1;
|
||||||
|
@ -899,14 +922,16 @@ tb_printinternal(PyTracebackObject *tb, PyObject *f, long limit,
|
||||||
depth--;
|
depth--;
|
||||||
tb = tb->tb_next;
|
tb = tb->tb_next;
|
||||||
}
|
}
|
||||||
while (tb != NULL && err == 0) {
|
while (tb != NULL) {
|
||||||
PyCodeObject *code = PyFrame_GetCode(tb->tb_frame);
|
code = PyFrame_GetCode(tb->tb_frame);
|
||||||
if (last_file == NULL ||
|
if (last_file == NULL ||
|
||||||
code->co_filename != last_file ||
|
code->co_filename != last_file ||
|
||||||
last_line == -1 || tb->tb_lineno != last_line ||
|
last_line == -1 || tb->tb_lineno != last_line ||
|
||||||
last_name == NULL || code->co_name != last_name) {
|
last_name == NULL || code->co_name != last_name) {
|
||||||
if (cnt > TB_RECURSIVE_CUTOFF) {
|
if (cnt > TB_RECURSIVE_CUTOFF) {
|
||||||
err = tb_print_line_repeated(f, cnt);
|
if (tb_print_line_repeated(f, cnt) < 0) {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
last_file = code->co_filename;
|
last_file = code->co_filename;
|
||||||
last_line = tb->tb_lineno;
|
last_line = tb->tb_lineno;
|
||||||
|
@ -914,20 +939,28 @@ tb_printinternal(PyTracebackObject *tb, PyObject *f, long limit,
|
||||||
cnt = 0;
|
cnt = 0;
|
||||||
}
|
}
|
||||||
cnt++;
|
cnt++;
|
||||||
if (err == 0 && cnt <= TB_RECURSIVE_CUTOFF) {
|
if (cnt <= TB_RECURSIVE_CUTOFF) {
|
||||||
err = tb_displayline(tb, f, code->co_filename, tb->tb_lineno,
|
if (tb_displayline(tb, f, code->co_filename, tb->tb_lineno,
|
||||||
tb->tb_frame, code->co_name, indent, margin);
|
tb->tb_frame, code->co_name, indent, margin) < 0) {
|
||||||
if (err == 0) {
|
goto error;
|
||||||
err = PyErr_CheckSignals();
|
}
|
||||||
|
|
||||||
|
if (PyErr_CheckSignals() < 0) {
|
||||||
|
goto error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Py_DECREF(code);
|
Py_CLEAR(code);
|
||||||
tb = tb->tb_next;
|
tb = tb->tb_next;
|
||||||
}
|
}
|
||||||
if (err == 0 && cnt > TB_RECURSIVE_CUTOFF) {
|
if (cnt > TB_RECURSIVE_CUTOFF) {
|
||||||
err = tb_print_line_repeated(f, cnt);
|
if (tb_print_line_repeated(f, cnt) < 0) {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return err;
|
return 0;
|
||||||
|
error:
|
||||||
|
Py_XDECREF(code);
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define PyTraceBack_LIMIT 1000
|
#define PyTraceBack_LIMIT 1000
|
||||||
|
@ -936,12 +969,12 @@ int
|
||||||
_PyTraceBack_Print_Indented(PyObject *v, int indent, const char *margin,
|
_PyTraceBack_Print_Indented(PyObject *v, int indent, const char *margin,
|
||||||
const char *header_margin, const char *header, PyObject *f)
|
const char *header_margin, const char *header, PyObject *f)
|
||||||
{
|
{
|
||||||
int err;
|
|
||||||
PyObject *limitv;
|
PyObject *limitv;
|
||||||
long limit = PyTraceBack_LIMIT;
|
long limit = PyTraceBack_LIMIT;
|
||||||
|
|
||||||
if (v == NULL)
|
if (v == NULL) {
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
if (!PyTraceBack_Check(v)) {
|
if (!PyTraceBack_Check(v)) {
|
||||||
PyErr_BadInternalCall();
|
PyErr_BadInternalCall();
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -957,14 +990,19 @@ _PyTraceBack_Print_Indented(PyObject *v, int indent, const char *margin,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
err = _Py_WriteIndentedMargin(indent, header_margin, f);
|
if (_Py_WriteIndentedMargin(indent, header_margin, f) < 0) {
|
||||||
if (err == 0) {
|
return -1;
|
||||||
err = PyFile_WriteString(header, f);
|
|
||||||
}
|
}
|
||||||
if (err == 0) {
|
|
||||||
err = tb_printinternal((PyTracebackObject *)v, f, limit, indent, margin);
|
if (PyFile_WriteString(header, f) < 0) {
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
return err;
|
|
||||||
|
if (tb_printinternal((PyTracebackObject *)v, f, limit, indent, margin) < 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue