summaryrefslogtreecommitdiffstats
path: root/Objects/exceptions.c
diff options
context:
space:
mode:
authorPablo Galindo <Pablogsal@gmail.com>2021-04-23 13:27:05 (GMT)
committerGitHub <noreply@github.com>2021-04-23 13:27:05 (GMT)
commita77aac4fca9723b8fd52a832f3e9df13beb25113 (patch)
treea504aa9fed91cd31849cdda3ecb1dad439a93778 /Objects/exceptions.c
parent91b69b77cf5f78de6d35dea23098df34b6fd9e53 (diff)
downloadcpython-a77aac4fca9723b8fd52a832f3e9df13beb25113.zip
cpython-a77aac4fca9723b8fd52a832f3e9df13beb25113.tar.gz
cpython-a77aac4fca9723b8fd52a832f3e9df13beb25113.tar.bz2
bpo-43914: Highlight invalid ranges in SyntaxErrors (#25525)
To improve the user experience understanding what part of the error messages associated with SyntaxErrors is wrong, we can highlight the whole error range and not only place the caret at the first character. In this way: >>> foo(x, z for z in range(10), t, w) File "<stdin>", line 1 foo(x, z for z in range(10), t, w) ^ SyntaxError: Generator expression must be parenthesized becomes >>> foo(x, z for z in range(10), t, w) File "<stdin>", line 1 foo(x, z for z in range(10), t, w) ^^^^^^^^^^^^^^^^^^^^ SyntaxError: Generator expression must be parenthesized
Diffstat (limited to 'Objects/exceptions.c')
-rw-r--r--Objects/exceptions.c45
1 files changed, 28 insertions, 17 deletions
diff --git a/Objects/exceptions.c b/Objects/exceptions.c
index 4a2fc27..95e6f21 100644
--- a/Objects/exceptions.c
+++ b/Objects/exceptions.c
@@ -1494,30 +1494,33 @@ SyntaxError_init(PySyntaxErrorObject *self, PyObject *args, PyObject *kwds)
if (lenargs == 2) {
info = PyTuple_GET_ITEM(args, 1);
info = PySequence_Tuple(info);
- if (!info)
+ if (!info) {
return -1;
+ }
- if (PyTuple_GET_SIZE(info) != 4) {
- /* not a very good error message, but it's what Python 2.4 gives */
- PyErr_SetString(PyExc_IndexError, "tuple index out of range");
+ self->end_lineno = NULL;
+ self->end_offset = NULL;
+ if (!PyArg_ParseTuple(info, "OOOO|OO",
+ &self->filename, &self->lineno,
+ &self->offset, &self->text,
+ &self->end_lineno, &self->end_offset)) {
Py_DECREF(info);
return -1;
- }
-
- Py_INCREF(PyTuple_GET_ITEM(info, 0));
- Py_XSETREF(self->filename, PyTuple_GET_ITEM(info, 0));
-
- Py_INCREF(PyTuple_GET_ITEM(info, 1));
- Py_XSETREF(self->lineno, PyTuple_GET_ITEM(info, 1));
-
- Py_INCREF(PyTuple_GET_ITEM(info, 2));
- Py_XSETREF(self->offset, PyTuple_GET_ITEM(info, 2));
-
- Py_INCREF(PyTuple_GET_ITEM(info, 3));
- Py_XSETREF(self->text, PyTuple_GET_ITEM(info, 3));
+ }
+ Py_INCREF(self->filename);
+ Py_INCREF(self->lineno);
+ Py_INCREF(self->offset);
+ Py_INCREF(self->text);
+ Py_XINCREF(self->end_lineno);
+ Py_XINCREF(self->end_offset);
Py_DECREF(info);
+ if (self->end_lineno != NULL && self->end_offset == NULL) {
+ PyErr_SetString(PyExc_TypeError, "end_offset must be provided when end_lineno is provided");
+ return -1;
+ }
+
/*
* Issue #21669: Custom error for 'print' & 'exec' as statements
*
@@ -1540,6 +1543,8 @@ SyntaxError_clear(PySyntaxErrorObject *self)
Py_CLEAR(self->filename);
Py_CLEAR(self->lineno);
Py_CLEAR(self->offset);
+ Py_CLEAR(self->end_lineno);
+ Py_CLEAR(self->end_offset);
Py_CLEAR(self->text);
Py_CLEAR(self->print_file_and_line);
return BaseException_clear((PyBaseExceptionObject *)self);
@@ -1560,6 +1565,8 @@ SyntaxError_traverse(PySyntaxErrorObject *self, visitproc visit, void *arg)
Py_VISIT(self->filename);
Py_VISIT(self->lineno);
Py_VISIT(self->offset);
+ Py_VISIT(self->end_lineno);
+ Py_VISIT(self->end_offset);
Py_VISIT(self->text);
Py_VISIT(self->print_file_and_line);
return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg);
@@ -1650,6 +1657,10 @@ static PyMemberDef SyntaxError_members[] = {
PyDoc_STR("exception offset")},
{"text", T_OBJECT, offsetof(PySyntaxErrorObject, text), 0,
PyDoc_STR("exception text")},
+ {"end_lineno", T_OBJECT, offsetof(PySyntaxErrorObject, end_lineno), 0,
+ PyDoc_STR("exception end lineno")},
+ {"end_offset", T_OBJECT, offsetof(PySyntaxErrorObject, end_offset), 0,
+ PyDoc_STR("exception end offset")},
{"print_file_and_line", T_OBJECT,
offsetof(PySyntaxErrorObject, print_file_and_line), 0,
PyDoc_STR("exception print_file_and_line")},