summaryrefslogtreecommitdiff
path: root/Python
diff options
context:
space:
mode:
authorPablo Galindo <Pablogsal@gmail.com>2021-04-23 14:27:05 +0100
committerGitHub <noreply@github.com>2021-04-23 14:27:05 +0100
commita77aac4fca9723b8fd52a832f3e9df13beb25113 (patch)
treea504aa9fed91cd31849cdda3ecb1dad439a93778 /Python
parent91b69b77cf5f78de6d35dea23098df34b6fd9e53 (diff)
downloadcpython-git-a77aac4fca9723b8fd52a832f3e9df13beb25113.tar.gz
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 'Python')
-rw-r--r--Python/compile.c13
-rw-r--r--Python/errors.c44
-rw-r--r--Python/pythonrun.c73
-rw-r--r--Python/symtable.c141
4 files changed, 209 insertions, 62 deletions
diff --git a/Python/compile.c b/Python/compile.c
index 49a713b2b0..1b7a2e83b1 100644
--- a/Python/compile.c
+++ b/Python/compile.c
@@ -197,6 +197,8 @@ struct compiler_unit {
int u_firstlineno; /* the first lineno of the block */
int u_lineno; /* the lineno for the current stmt */
int u_col_offset; /* the offset of the current stmt */
+ int u_end_lineno; /* the end line of the current stmt */
+ int u_end_col_offset; /* the end offset of the current stmt */
};
/* This struct captures the global state of a compilation.
@@ -641,6 +643,8 @@ compiler_enter_scope(struct compiler *c, identifier name,
u->u_firstlineno = lineno;
u->u_lineno = 0;
u->u_col_offset = 0;
+ u->u_end_lineno = 0;
+ u->u_end_col_offset = 0;
u->u_consts = PyDict_New();
if (!u->u_consts) {
compiler_unit_free(u);
@@ -911,7 +915,9 @@ compiler_next_instr(basicblock *b)
#define SET_LOC(c, x) \
(c)->u->u_lineno = (x)->lineno; \
- (c)->u->u_col_offset = (x)->col_offset;
+ (c)->u->u_col_offset = (x)->col_offset; \
+ (c)->u->u_end_lineno = (x)->end_lineno; \
+ (c)->u->u_end_col_offset = (x)->end_col_offset;
/* Return the stack effect of opcode with argument oparg.
@@ -5474,8 +5480,9 @@ compiler_error(struct compiler *c, const char *format, ...)
Py_INCREF(Py_None);
loc = Py_None;
}
- PyObject *args = Py_BuildValue("O(OiiO)", msg, c->c_filename,
- c->u->u_lineno, c->u->u_col_offset + 1, loc);
+ PyObject *args = Py_BuildValue("O(OiiOii)", msg, c->c_filename,
+ c->u->u_lineno, c->u->u_col_offset + 1, loc,
+ c->u->u_end_lineno, c->u->u_end_col_offset + 1);
Py_DECREF(msg);
if (args == NULL) {
goto exit;
diff --git a/Python/errors.c b/Python/errors.c
index d73ba93b02..f743d3089e 100644
--- a/Python/errors.c
+++ b/Python/errors.c
@@ -1545,14 +1545,17 @@ PyErr_SyntaxLocation(const char *filename, int lineno)
If the exception is not a SyntaxError, also sets additional attributes
to make printing of exceptions believe it is a syntax error. */
-void
-PyErr_SyntaxLocationObject(PyObject *filename, int lineno, int col_offset)
+static void
+PyErr_SyntaxLocationObjectEx(PyObject *filename, int lineno, int col_offset,
+ int end_lineno, int end_col_offset)
{
PyObject *exc, *v, *tb, *tmp;
_Py_IDENTIFIER(filename);
_Py_IDENTIFIER(lineno);
+ _Py_IDENTIFIER(end_lineno);
_Py_IDENTIFIER(msg);
_Py_IDENTIFIER(offset);
+ _Py_IDENTIFIER(end_offset);
_Py_IDENTIFIER(print_file_and_line);
_Py_IDENTIFIER(text);
PyThreadState *tstate = _PyThreadState_GET();
@@ -1582,6 +1585,32 @@ PyErr_SyntaxLocationObject(PyObject *filename, int lineno, int col_offset)
_PyErr_Clear(tstate);
}
Py_XDECREF(tmp);
+
+ tmp = NULL;
+ if (end_lineno >= 0) {
+ tmp = PyLong_FromLong(end_lineno);
+ if (tmp == NULL) {
+ _PyErr_Clear(tstate);
+ }
+ }
+ if (_PyObject_SetAttrId(v, &PyId_end_lineno, tmp ? tmp : Py_None)) {
+ _PyErr_Clear(tstate);
+ }
+ Py_XDECREF(tmp);
+
+ tmp = NULL;
+ if (end_col_offset >= 0) {
+ tmp = PyLong_FromLong(end_col_offset);
+ if (tmp == NULL) {
+ _PyErr_Clear(tstate);
+ }
+ }
+ if (_PyObject_SetAttrId(v, &PyId_end_offset, tmp ? tmp : Py_None)) {
+ _PyErr_Clear(tstate);
+ }
+ Py_XDECREF(tmp);
+
+ tmp = NULL;
if (filename != NULL) {
if (_PyObject_SetAttrId(v, &PyId_filename, filename)) {
_PyErr_Clear(tstate);
@@ -1634,6 +1663,17 @@ PyErr_SyntaxLocationObject(PyObject *filename, int lineno, int col_offset)
}
void
+PyErr_SyntaxLocationObject(PyObject *filename, int lineno, int col_offset) {
+ PyErr_SyntaxLocationObjectEx(filename, lineno, col_offset, lineno, -1);
+}
+
+void
+PyErr_RangedSyntaxLocationObject(PyObject *filename, int lineno, int col_offset,
+ int end_lineno, int end_col_offset) {
+ PyErr_SyntaxLocationObjectEx(filename, lineno, col_offset, end_lineno, end_col_offset);
+}
+
+void
PyErr_SyntaxLocationEx(const char *filename, int lineno, int col_offset)
{
PyThreadState *tstate = _PyThreadState_GET();
diff --git a/Python/pythonrun.c b/Python/pythonrun.c
index 8bd31348b2..f00e3eb0de 100644
--- a/Python/pythonrun.c
+++ b/Python/pythonrun.c
@@ -510,7 +510,9 @@ PyRun_SimpleStringFlags(const char *command, PyCompilerFlags *flags)
static int
parse_syntax_error(PyObject *err, PyObject **message, PyObject **filename,
- Py_ssize_t *lineno, Py_ssize_t *offset, PyObject **text)
+ Py_ssize_t *lineno, Py_ssize_t *offset,
+ Py_ssize_t* end_lineno, Py_ssize_t* end_offset,
+ PyObject **text)
{
Py_ssize_t hold;
PyObject *v;
@@ -518,6 +520,8 @@ parse_syntax_error(PyObject *err, PyObject **message, PyObject **filename,
_Py_IDENTIFIER(filename);
_Py_IDENTIFIER(lineno);
_Py_IDENTIFIER(offset);
+ _Py_IDENTIFIER(end_lineno);
+ _Py_IDENTIFIER(end_offset);
_Py_IDENTIFIER(text);
*message = NULL;
@@ -565,6 +569,44 @@ parse_syntax_error(PyObject *err, PyObject **message, PyObject **filename,
*offset = hold;
}
+ if (Py_TYPE(err) == (PyTypeObject*)PyExc_SyntaxError) {
+ v = _PyObject_GetAttrId(err, &PyId_end_lineno);
+ if (!v) {
+ PyErr_Clear();
+ *end_lineno = *lineno;
+ }
+ else if (v == Py_None) {
+ *end_lineno = *lineno;
+ Py_DECREF(v);
+ } else {
+ hold = PyLong_AsSsize_t(v);
+ Py_DECREF(v);
+ if (hold < 0 && PyErr_Occurred())
+ goto finally;
+ *end_lineno = hold;
+ }
+
+ v = _PyObject_GetAttrId(err, &PyId_end_offset);
+ if (!v) {
+ PyErr_Clear();
+ *end_offset = -1;
+ }
+ else if (v == Py_None) {
+ *end_offset = -1;
+ Py_DECREF(v);
+ } else {
+ hold = PyLong_AsSsize_t(v);
+ Py_DECREF(v);
+ if (hold < 0 && PyErr_Occurred())
+ goto finally;
+ *end_offset = hold;
+ }
+ } else {
+ // SyntaxError subclasses
+ *end_lineno = *lineno;
+ *end_offset = -1;
+ }
+
v = _PyObject_GetAttrId(err, &PyId_text);
if (!v)
goto finally;
@@ -584,8 +626,9 @@ finally:
}
static void
-print_error_text(PyObject *f, Py_ssize_t offset, PyObject *text_obj)
+print_error_text(PyObject *f, Py_ssize_t offset, Py_ssize_t end_offset, PyObject *text_obj)
{
+ size_t caret_repetitions = (end_offset > 0 && end_offset > offset) ? end_offset - offset : 1;
/* Convert text to a char pointer; return if error */
const char *text = PyUnicode_AsUTF8(text_obj);
if (text == NULL)
@@ -645,7 +688,10 @@ print_error_text(PyObject *f, Py_ssize_t offset, PyObject *text_obj)
while (--offset >= 0) {
PyFile_WriteString(" ", f);
}
- PyFile_WriteString("^\n", f);
+ for (size_t caret_iter=0; caret_iter < caret_repetitions ; caret_iter++) {
+ PyFile_WriteString("^", f);
+ }
+ PyFile_WriteString("\n", f);
}
@@ -865,11 +911,12 @@ print_exception(PyObject *f, PyObject *value)
(err = _PyObject_LookupAttrId(value, &PyId_print_file_and_line, &tmp)) > 0)
{
PyObject *message, *filename, *text;
- Py_ssize_t lineno, offset;
+ Py_ssize_t lineno, offset, end_lineno, end_offset;
err = 0;
Py_DECREF(tmp);
if (!parse_syntax_error(value, &message, &filename,
- &lineno, &offset, &text))
+ &lineno, &offset,
+ &end_lineno, &end_offset, &text))
PyErr_Clear();
else {
PyObject *line;
@@ -886,7 +933,21 @@ print_exception(PyObject *f, PyObject *value)
}
if (text != NULL) {
- print_error_text(f, offset, text);
+ Py_ssize_t line_size;
+ const char* error_line = PyUnicode_AsUTF8AndSize(text, &line_size);
+ // If the location of the error spawn multiple lines, we want
+ // to just print the first one and highlight everything until
+ // the end of that one since we don't support multi-line error
+ // messages.
+ if (end_lineno > lineno) {
+ end_offset = (error_line != NULL) ? line_size : -1;
+ }
+ // Limit the ammount of '^' that we can display to
+ // the size of the text in the source line.
+ if (error_line != NULL && end_offset > line_size + 1) {
+ end_offset = line_size + 1;
+ }
+ print_error_text(f, offset, end_offset, text);
Py_DECREF(text);
}
diff --git a/Python/symtable.c b/Python/symtable.c
index d148a563a3..c6f8694578 100644
--- a/Python/symtable.c
+++ b/Python/symtable.c
@@ -47,7 +47,8 @@
static PySTEntryObject *
ste_new(struct symtable *st, identifier name, _Py_block_ty block,
- void *key, int lineno, int col_offset)
+ void *key, int lineno, int col_offset,
+ int end_lineno, int end_col_offset)
{
PySTEntryObject *ste = NULL;
PyObject *k = NULL;
@@ -81,6 +82,8 @@ ste_new(struct symtable *st, identifier name, _Py_block_ty block,
ste->ste_opt_col_offset = 0;
ste->ste_lineno = lineno;
ste->ste_col_offset = col_offset;
+ ste->ste_end_lineno = end_lineno;
+ ste->ste_end_col_offset = end_col_offset;
if (st->st_cur != NULL &&
(st->st_cur->ste_nested ||
@@ -190,8 +193,9 @@ PyTypeObject PySTEntry_Type = {
static int symtable_analyze(struct symtable *st);
static int symtable_enter_block(struct symtable *st, identifier name,
- _Py_block_ty block, void *ast, int lineno,
- int col_offset);
+ _Py_block_ty block, void *ast,
+ int lineno, int col_offset,
+ int end_lineno, int end_col_offset);
static int symtable_exit_block(struct symtable *st);
static int symtable_visit_stmt(struct symtable *st, stmt_ty s);
static int symtable_visit_expr(struct symtable *st, expr_ty s);
@@ -296,7 +300,7 @@ _PySymtable_Build(mod_ty mod, PyObject *filename, PyFutureFeatures *future)
/* Make the initial symbol information gathering pass */
if (!GET_IDENTIFIER(top) ||
- !symtable_enter_block(st, top, ModuleBlock, (void *)mod, 0, 0)) {
+ !symtable_enter_block(st, top, ModuleBlock, (void *)mod, 0, 0, 0, 0)) {
_PySymtable_Free(st);
return NULL;
}
@@ -409,9 +413,11 @@ error_at_directive(PySTEntryObject *ste, PyObject *name)
assert(PyTuple_CheckExact(data));
assert(PyUnicode_CheckExact(PyTuple_GET_ITEM(data, 0)));
if (PyUnicode_Compare(PyTuple_GET_ITEM(data, 0), name) == 0) {
- PyErr_SyntaxLocationObject(ste->ste_table->st_filename,
- PyLong_AsLong(PyTuple_GET_ITEM(data, 1)),
- PyLong_AsLong(PyTuple_GET_ITEM(data, 2)) + 1);
+ PyErr_RangedSyntaxLocationObject(ste->ste_table->st_filename,
+ PyLong_AsLong(PyTuple_GET_ITEM(data, 1)),
+ PyLong_AsLong(PyTuple_GET_ITEM(data, 2)) + 1,
+ PyLong_AsLong(PyTuple_GET_ITEM(data, 3)),
+ PyLong_AsLong(PyTuple_GET_ITEM(data, 4)) + 1);
return 0;
}
@@ -958,11 +964,12 @@ symtable_exit_block(struct symtable *st)
static int
symtable_enter_block(struct symtable *st, identifier name, _Py_block_ty block,
- void *ast, int lineno, int col_offset)
+ void *ast, int lineno, int col_offset,
+ int end_lineno, int end_col_offset)
{
PySTEntryObject *prev = NULL, *ste;
- ste = ste_new(st, name, block, ast, lineno, col_offset);
+ ste = ste_new(st, name, block, ast, lineno, col_offset, end_lineno, end_col_offset);
if (ste == NULL)
return 0;
if (PyList_Append(st->st_stack, (PyObject *)ste) < 0) {
@@ -1018,9 +1025,11 @@ symtable_add_def_helper(struct symtable *st, PyObject *name, int flag, struct _s
if ((flag & DEF_PARAM) && (val & DEF_PARAM)) {
/* Is it better to use 'mangled' or 'name' here? */
PyErr_Format(PyExc_SyntaxError, DUPLICATE_ARGUMENT, name);
- PyErr_SyntaxLocationObject(st->st_filename,
- ste->ste_lineno,
- ste->ste_col_offset + 1);
+ PyErr_RangedSyntaxLocationObject(st->st_filename,
+ ste->ste_lineno,
+ ste->ste_col_offset + 1,
+ ste->ste_end_lineno,
+ ste->ste_end_col_offset + 1);
goto error;
}
val |= flag;
@@ -1040,9 +1049,11 @@ symtable_add_def_helper(struct symtable *st, PyObject *name, int flag, struct _s
if (val & (DEF_GLOBAL | DEF_NONLOCAL)) {
PyErr_Format(PyExc_SyntaxError,
NAMED_EXPR_COMP_INNER_LOOP_CONFLICT, name);
- PyErr_SyntaxLocationObject(st->st_filename,
- ste->ste_lineno,
- ste->ste_col_offset + 1);
+ PyErr_RangedSyntaxLocationObject(st->st_filename,
+ ste->ste_lineno,
+ ste->ste_col_offset + 1,
+ ste->ste_end_lineno,
+ ste->ste_end_col_offset + 1);
goto error;
}
val |= DEF_COMP_ITER;
@@ -1141,7 +1152,8 @@ symtable_add_def(struct symtable *st, PyObject *name, int flag) {
}
static int
-symtable_record_directive(struct symtable *st, identifier name, int lineno, int col_offset)
+symtable_record_directive(struct symtable *st, identifier name, int lineno,
+ int col_offset, int end_lineno, int end_col_offset)
{
PyObject *data, *mangled;
int res;
@@ -1153,7 +1165,7 @@ symtable_record_directive(struct symtable *st, identifier name, int lineno, int
mangled = _Py_Mangle(st->st_private, name);
if (!mangled)
return 0;
- data = Py_BuildValue("(Nii)", mangled, lineno, col_offset);
+ data = Py_BuildValue("(Niiii)", mangled, lineno, col_offset, end_lineno, end_col_offset);
if (!data)
return 0;
res = PyList_Append(st->st_cur->ste_directives, data);
@@ -1184,8 +1196,9 @@ symtable_visit_stmt(struct symtable *st, stmt_ty s)
if (s->v.FunctionDef.decorator_list)
VISIT_SEQ(st, expr, s->v.FunctionDef.decorator_list);
if (!symtable_enter_block(st, s->v.FunctionDef.name,
- FunctionBlock, (void *)s, s->lineno,
- s->col_offset))
+ FunctionBlock, (void *)s,
+ s->lineno, s->col_offset,
+ s->end_lineno, s->end_col_offset))
VISIT_QUIT(st, 0);
VISIT(st, arguments, s->v.FunctionDef.args);
VISIT_SEQ(st, stmt, s->v.FunctionDef.body);
@@ -1201,7 +1214,8 @@ symtable_visit_stmt(struct symtable *st, stmt_ty s)
if (s->v.ClassDef.decorator_list)
VISIT_SEQ(st, expr, s->v.ClassDef.decorator_list);
if (!symtable_enter_block(st, s->v.ClassDef.name, ClassBlock,
- (void *)s, s->lineno, s->col_offset))
+ (void *)s, s->lineno, s->col_offset,
+ s->end_lineno, s->end_col_offset))
VISIT_QUIT(st, 0);
tmp = st->st_private;
st->st_private = s->v.ClassDef.name;
@@ -1237,9 +1251,11 @@ symtable_visit_stmt(struct symtable *st, stmt_ty s)
PyErr_Format(PyExc_SyntaxError,
cur & DEF_GLOBAL ? GLOBAL_ANNOT : NONLOCAL_ANNOT,
e_name->v.Name.id);
- PyErr_SyntaxLocationObject(st->st_filename,
- s->lineno,
- s->col_offset + 1);
+ PyErr_RangedSyntaxLocationObject(st->st_filename,
+ s->lineno,
+ s->col_offset + 1,
+ s->end_lineno,
+ s->end_col_offset + 1);
VISIT_QUIT(st, 0);
}
if (s->v.AnnAssign.simple &&
@@ -1336,14 +1352,17 @@ symtable_visit_stmt(struct symtable *st, stmt_ty s)
}
PyErr_Format(PyExc_SyntaxError,
msg, name);
- PyErr_SyntaxLocationObject(st->st_filename,
- s->lineno,
- s->col_offset + 1);
+ PyErr_RangedSyntaxLocationObject(st->st_filename,
+ s->lineno,
+ s->col_offset + 1,
+ s->end_lineno,
+ s->end_col_offset + 1);
VISIT_QUIT(st, 0);
}
if (!symtable_add_def(st, name, DEF_GLOBAL))
VISIT_QUIT(st, 0);
- if (!symtable_record_directive(st, name, s->lineno, s->col_offset))
+ if (!symtable_record_directive(st, name, s->lineno, s->col_offset,
+ s->end_lineno, s->end_col_offset))
VISIT_QUIT(st, 0);
}
break;
@@ -1368,14 +1387,17 @@ symtable_visit_stmt(struct symtable *st, stmt_ty s)
msg = NONLOCAL_AFTER_ASSIGN;
}
PyErr_Format(PyExc_SyntaxError, msg, name);
- PyErr_SyntaxLocationObject(st->st_filename,
- s->lineno,
- s->col_offset + 1);
+ PyErr_RangedSyntaxLocationObject(st->st_filename,
+ s->lineno,
+ s->col_offset + 1,
+ s->end_lineno,
+ s->end_col_offset + 1);
VISIT_QUIT(st, 0);
}
if (!symtable_add_def(st, name, DEF_NONLOCAL))
VISIT_QUIT(st, 0);
- if (!symtable_record_directive(st, name, s->lineno, s->col_offset))
+ if (!symtable_record_directive(st, name, s->lineno, s->col_offset,
+ s->end_lineno, s->end_col_offset))
VISIT_QUIT(st, 0);
}
break;
@@ -1406,8 +1428,9 @@ symtable_visit_stmt(struct symtable *st, stmt_ty s)
if (s->v.AsyncFunctionDef.decorator_list)
VISIT_SEQ(st, expr, s->v.AsyncFunctionDef.decorator_list);
if (!symtable_enter_block(st, s->v.AsyncFunctionDef.name,
- FunctionBlock, (void *)s, s->lineno,
- s->col_offset))
+ FunctionBlock, (void *)s,
+ s->lineno, s->col_offset,
+ s->end_lineno, s->end_col_offset))
VISIT_QUIT(st, 0);
st->st_cur->ste_coroutine = 1;
VISIT(st, arguments, s->v.AsyncFunctionDef.args);
@@ -1453,9 +1476,11 @@ symtable_extend_namedexpr_scope(struct symtable *st, expr_ty e)
long target_in_scope = _PyST_GetSymbol(ste, target_name);
if (target_in_scope & DEF_COMP_ITER) {
PyErr_Format(PyExc_SyntaxError, NAMED_EXPR_COMP_CONFLICT, target_name);
- PyErr_SyntaxLocationObject(st->st_filename,
- e->lineno,
- e->col_offset);
+ PyErr_RangedSyntaxLocationObject(st->st_filename,
+ e->lineno,
+ e->col_offset + 1,
+ e->end_lineno,
+ e->end_col_offset + 1);
VISIT_QUIT(st, 0);
}
continue;
@@ -1471,7 +1496,8 @@ symtable_extend_namedexpr_scope(struct symtable *st, expr_ty e)
if (!symtable_add_def(st, target_name, DEF_NONLOCAL))
VISIT_QUIT(st, 0);
}
- if (!symtable_record_directive(st, target_name, e->lineno, e->col_offset))
+ if (!symtable_record_directive(st, target_name, e->lineno, e->col_offset,
+ e->end_lineno, e->end_col_offset))
VISIT_QUIT(st, 0);
return symtable_add_def_helper(st, target_name, DEF_LOCAL, ste);
@@ -1480,7 +1506,8 @@ symtable_extend_namedexpr_scope(struct symtable *st, expr_ty e)
if (ste->ste_type == ModuleBlock) {
if (!symtable_add_def(st, target_name, DEF_GLOBAL))
VISIT_QUIT(st, 0);
- if (!symtable_record_directive(st, target_name, e->lineno, e->col_offset))
+ if (!symtable_record_directive(st, target_name, e->lineno, e->col_offset,
+ e->end_lineno, e->end_col_offset))
VISIT_QUIT(st, 0);
return symtable_add_def_helper(st, target_name, DEF_GLOBAL, ste);
@@ -1488,9 +1515,11 @@ symtable_extend_namedexpr_scope(struct symtable *st, expr_ty e)
/* Disallow usage in ClassBlock */
if (ste->ste_type == ClassBlock) {
PyErr_Format(PyExc_SyntaxError, NAMED_EXPR_COMP_IN_CLASS);
- PyErr_SyntaxLocationObject(st->st_filename,
- e->lineno,
- e->col_offset);
+ PyErr_RangedSyntaxLocationObject(st->st_filename,
+ e->lineno,
+ e->col_offset + 1,
+ e->end_lineno,
+ e->end_col_offset + 1);
VISIT_QUIT(st, 0);
}
}
@@ -1508,9 +1537,11 @@ symtable_handle_namedexpr(struct symtable *st, expr_ty e)
if (st->st_cur->ste_comp_iter_expr > 0) {
/* Assignment isn't allowed in a comprehension iterable expression */
PyErr_Format(PyExc_SyntaxError, NAMED_EXPR_COMP_ITER_EXPR);
- PyErr_SyntaxLocationObject(st->st_filename,
- e->lineno,
- e->col_offset);
+ PyErr_RangedSyntaxLocationObject(st->st_filename,
+ e->lineno,
+ e->col_offset + 1,
+ e->end_lineno,
+ e->end_col_offset + 1);
return 0;
}
if (st->st_cur->ste_comprehension) {
@@ -1554,8 +1585,9 @@ symtable_visit_expr(struct symtable *st, expr_ty e)
if (e->v.Lambda.args->kw_defaults)
VISIT_SEQ_WITH_NULL(st, expr, e->v.Lambda.args->kw_defaults);
if (!symtable_enter_block(st, lambda,
- FunctionBlock, (void *)e, e->lineno,
- e->col_offset))
+ FunctionBlock, (void *)e,
+ e->lineno, e->col_offset,
+ e->end_lineno, e->end_col_offset))
VISIT_QUIT(st, 0);
VISIT(st, arguments, e->v.Lambda.args);
VISIT(st, expr, e->v.Lambda.body);
@@ -1839,8 +1871,12 @@ symtable_visit_alias(struct symtable *st, alias_ty a)
if (st->st_cur->ste_type != ModuleBlock) {
int lineno = st->st_cur->ste_lineno;
int col_offset = st->st_cur->ste_col_offset;
+ int end_lineno = st->st_cur->ste_end_lineno;
+ int end_col_offset = st->st_cur->ste_end_col_offset;
PyErr_SetString(PyExc_SyntaxError, IMPORT_STAR_WARNING);
- PyErr_SyntaxLocationObject(st->st_filename, lineno, col_offset + 1);
+ PyErr_RangedSyntaxLocationObject(st->st_filename,
+ lineno, col_offset + 1,
+ end_lineno, end_col_offset + 1);
Py_DECREF(store_name);
return 0;
}
@@ -1890,7 +1926,8 @@ symtable_handle_comprehension(struct symtable *st, expr_ty e,
/* Create comprehension scope for the rest */
if (!scope_name ||
!symtable_enter_block(st, scope_name, FunctionBlock, (void *)e,
- e->lineno, e->col_offset)) {
+ e->lineno, e->col_offset,
+ e->end_lineno, e->end_col_offset)) {
return 0;
}
if (outermost->is_async) {
@@ -1919,9 +1956,11 @@ symtable_handle_comprehension(struct symtable *st, expr_ty e,
(e->kind == SetComp_kind) ? "'yield' inside set comprehension" :
(e->kind == DictComp_kind) ? "'yield' inside dict comprehension" :
"'yield' inside generator expression");
- PyErr_SyntaxLocationObject(st->st_filename,
- st->st_cur->ste_lineno,
- st->st_cur->ste_col_offset + 1);
+ PyErr_RangedSyntaxLocationObject(st->st_filename,
+ st->st_cur->ste_lineno,
+ st->st_cur->ste_col_offset + 1,
+ st->st_cur->ste_end_lineno,
+ st->st_cur->ste_end_col_offset + 1);
symtable_exit_block(st);
return 0;
}