diff --git a/Doc/data/python3.10.abi b/Doc/data/python3.10.abi
index 94dcf74411b4b0..b7886ae28f7007 100644
--- a/Doc/data/python3.10.abi
+++ b/Doc/data/python3.10.abi
@@ -1005,6 +1005,7 @@
+
@@ -1641,10 +1642,7 @@
-
-
-
-
+
@@ -1820,13 +1818,13 @@
-
+
-
+
@@ -1898,15 +1896,15 @@
-
-
-
+
+
+
@@ -1916,7 +1914,7 @@
-
+
@@ -1952,66 +1950,66 @@
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
@@ -2020,82 +2018,82 @@
-
+
-
+
-
+
-
+
-
+
+
+
+
-
+
-
+
-
+
-
+
-
-
-
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
@@ -2104,16 +2102,16 @@
-
+
-
+
-
+
@@ -2122,10 +2120,10 @@
-
+
-
+
@@ -2149,16 +2147,16 @@
-
+
-
+
-
+
-
+
@@ -2167,46 +2165,46 @@
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
@@ -2215,13 +2213,13 @@
-
+
-
+
-
+
@@ -2260,19 +2258,19 @@
-
+
-
+
-
+
-
+
@@ -2314,10 +2312,10 @@
-
+
-
+
@@ -2325,22 +2323,19 @@
-
-
-
-
+
-
+
-
+
@@ -2367,7 +2362,7 @@
-
+
@@ -2375,113 +2370,113 @@
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
@@ -2491,16 +2486,16 @@
-
+
-
+
-
+
-
+
@@ -3012,23 +3007,23 @@
-
-
+
+
-
+
-
+
-
+
-
+
-
+
@@ -3368,7 +3363,7 @@
-
+
@@ -3410,13 +3405,7 @@
-
-
-
-
-
-
-
+
@@ -3425,9 +3414,6 @@
-
-
-
@@ -3456,50 +3442,50 @@
-
-
+
+
-
-
+
+
-
-
-
-
+
+
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
-
+
+
+
-
-
-
+
+
+
-
-
-
+
+
+
-
-
-
+
+
+
@@ -3927,7 +3913,7 @@
-
+
@@ -3979,12 +3965,12 @@
-
-
+
+
-
-
+
+
@@ -4371,7 +4357,7 @@
-
+
@@ -4764,105 +4750,105 @@
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
@@ -5116,27 +5102,27 @@
-
+
-
+
-
+
-
+
-
+
-
+
-
+
@@ -5323,39 +5309,39 @@
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
@@ -5513,192 +5499,192 @@
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
-
+
+
@@ -5868,7 +5854,7 @@
-
+
@@ -7052,7 +7038,7 @@
-
+
@@ -7153,8 +7139,8 @@
-
-
+
+
@@ -8046,38 +8032,38 @@
-
-
-
-
+
+
+
+
-
-
-
-
+
+
+
+
-
-
+
+
-
-
-
-
+
+
+
+
-
-
+
+
-
-
+
+
@@ -8413,11 +8399,11 @@
-
+
-
+
@@ -8985,7 +8971,7 @@
-
+
@@ -9962,7 +9948,7 @@
-
+
@@ -10104,6 +10090,9 @@
+
+
+
@@ -10320,7 +10309,7 @@
-
+
@@ -10788,8 +10777,8 @@
-
-
+
+
@@ -11691,7 +11680,7 @@
-
+
@@ -11745,7 +11734,7 @@
-
+
@@ -11814,7 +11803,7 @@
-
+
@@ -12319,30 +12308,30 @@
-
-
+
+
-
-
+
+
-
-
-
+
+
+
-
-
-
+
+
+
-
-
+
+
-
-
+
+
@@ -12355,21 +12344,21 @@
-
-
+
+
-
+
-
+
-
-
+
+
-
+
@@ -12430,125 +12419,125 @@
-
+
-
+
-
-
+
+
-
+
-
-
+
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
@@ -12768,36 +12757,36 @@
-
-
-
+
+
+
-
-
-
+
+
+
-
-
-
-
+
+
+
+
-
-
-
+
+
+
-
-
-
-
+
+
+
+
-
-
-
+
+
+
@@ -13229,22 +13218,22 @@
-
-
-
-
-
+
+
+
+
+
-
-
-
+
+
+
-
-
-
-
+
+
+
+
@@ -14513,17 +14502,20 @@
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
@@ -14533,7 +14525,7 @@
-
+
@@ -14545,10 +14537,10 @@
-
+
-
+
@@ -14557,7 +14549,7 @@
-
+
@@ -14599,7 +14591,7 @@
-
+
@@ -14651,14 +14643,20 @@
-
-
-
+
+
+
+
+
+
+
+
+
-
-
-
+
+
+
@@ -14714,105 +14712,105 @@
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
@@ -15211,10 +15209,10 @@
-
+
-
+
@@ -15235,7 +15233,7 @@
-
+
@@ -15775,7 +15773,7 @@
-
+
@@ -15954,27 +15952,27 @@
-
+
-
+
-
+
-
+
-
+
-
+
-
+
@@ -16148,6 +16146,9 @@
+
+
+
@@ -16466,7 +16467,7 @@
-
+
@@ -16933,7 +16934,7 @@
-
+
@@ -17137,7 +17138,7 @@
-
+
@@ -17224,51 +17225,51 @@
-
+
-
-
+
+
-
-
+
+
-
-
-
+
+
+
-
-
+
+
-
-
+
+
-
-
-
+
+
+
-
+
-
-
+
+
-
-
+
+
-
-
-
+
+
+
-
+
@@ -17278,175 +17279,175 @@
-
-
+
+
-
+
-
+
-
+
-
+
-
+
-
+
-
-
+
+
-
-
+
+
-
-
+
+
-
+
-
+
-
-
-
+
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
+
-
-
+
+
-
-
+
+
-
-
-
+
+
+
-
+
-
+
-
-
-
+
+
+
-
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
-
+
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
-
+
+
+
-
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
+
-
-
+
+
@@ -17457,21 +17458,21 @@
-
+
-
-
+
+
-
-
+
+
-
-
-
-
+
+
+
+
@@ -17534,7 +17535,7 @@
-
+
@@ -18080,135 +18081,144 @@
-
-
+
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
-
-
-
-
-
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
+
-
+
-
+
-
+
-
+
-
+
+
+
+
+
+
+
-
+
-
-
+
+
+
+
+
+
+
+
+
+
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
-
+
+
@@ -18216,15 +18226,15 @@
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
@@ -18389,10 +18399,10 @@
-
+
-
+
@@ -18424,17 +18434,17 @@
-
+
-
+
-
+
-
+
@@ -18444,16 +18454,16 @@
-
+
-
+
-
+
@@ -18484,27 +18494,27 @@
-
+
-
+
-
+
-
+
-
+
@@ -18525,7 +18535,7 @@
-
+
@@ -18631,13 +18641,13 @@
-
+
-
+
-
+
@@ -18683,14 +18693,14 @@
-
+
-
+
@@ -18704,7 +18714,7 @@
-
+
@@ -18712,19 +18722,19 @@
-
-
+
+
-
+
-
+
@@ -18828,7 +18838,7 @@
-
+
@@ -18902,9 +18912,9 @@
-
+
-
+
@@ -19002,39 +19012,39 @@
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
@@ -19046,46 +19056,46 @@
-
+
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
@@ -19093,23 +19103,23 @@
-
+
-
+
-
+
-
+
@@ -19181,20 +19191,20 @@
-
-
-
-
+
+
+
+
-
+
-
+
@@ -19275,10 +19285,10 @@
-
+
-
+
@@ -19385,7 +19395,7 @@
-
+
@@ -19393,18 +19403,18 @@
-
-
+
+
-
+
-
-
+
+
-
+
@@ -19420,15 +19430,15 @@
-
+
-
+
-
-
+
+
@@ -20215,42 +20225,42 @@
-
+
-
+
-
+
-
+
-
+
-
-
+
+
-
+
-
+
-
+
-
-
+
+
-
-
+
+
@@ -20286,7 +20296,7 @@
-
+
@@ -20409,7 +20419,7 @@
-
+
@@ -20681,7 +20691,7 @@
-
+
@@ -20691,7 +20701,7 @@
-
+
@@ -20702,8 +20712,8 @@
-
-
-
+
+
+
diff --git a/Include/internal/pycore_symtable.h b/Include/internal/pycore_symtable.h
index f3505f8949be4b..a2e520b8e25fe0 100644
--- a/Include/internal/pycore_symtable.h
+++ b/Include/internal/pycore_symtable.h
@@ -13,6 +13,13 @@ struct _mod; // Type defined in pycore_ast.h
typedef enum _block_type { FunctionBlock, ClassBlock, ModuleBlock, AnnotationBlock }
_Py_block_ty;
+typedef enum _comprehension_type {
+ NoComprehension = 0,
+ ListComprehension = 1,
+ DictComprehension = 2,
+ SetComprehension = 3,
+ GeneratorExpression = 4 } _Py_comprehension_ty;
+
struct _symtable_entry;
struct symtable {
@@ -42,14 +49,14 @@ typedef struct _symtable_entry {
PyObject *ste_varnames; /* list of function parameters */
PyObject *ste_children; /* list of child blocks */
PyObject *ste_directives;/* locations of global and nonlocal statements */
- _Py_block_ty ste_type; /* module, class, or function */
+ _Py_block_ty ste_type; /* module, class or function */
int ste_nested; /* true if block is nested */
unsigned ste_free : 1; /* true if block has free variables */
unsigned ste_child_free : 1; /* true if a child block has free vars,
including free refs to globals */
unsigned ste_generator : 1; /* true if namespace is a generator */
unsigned ste_coroutine : 1; /* true if namespace is a coroutine */
- unsigned ste_comprehension : 1; /* true if namespace is a list comprehension */
+ _Py_comprehension_ty ste_comprehension; /* Kind of comprehension (if any) */
unsigned ste_varargs : 1; /* true if block has varargs */
unsigned ste_varkeywords : 1; /* true if block has varkeywords */
unsigned ste_returns_value : 1; /* true if namespace uses return with
diff --git a/Lib/test/test_exceptions.py b/Lib/test/test_exceptions.py
index bc5f83a5d2dc89..9acb16c5182108 100644
--- a/Lib/test/test_exceptions.py
+++ b/Lib/test/test_exceptions.py
@@ -268,9 +268,10 @@ def baz():
check(b"\xef\xbb\xbf#coding: utf8\nprint('\xe6\x88\x91')\n", 0, -1)
# Errors thrown by symtable.c
- check('x = [(yield i) for i in range(3)]', 1, 5)
- check('def f():\n from _ import *', 1, 1)
- check('def f(x, x):\n pass', 1, 1)
+ check('x = [(yield i) for i in range(3)]', 1, 7)
+ check('def f():\n from _ import *', 2, 17)
+ check('def f(x, x):\n pass', 1, 10)
+ check('{i for i in range(5) if (j := 0) for j in range(5)}', 1, 38)
check('def f(x):\n nonlocal x', 2, 3)
check('def f(x):\n x = 1\n global x', 3, 3)
check('nonlocal x', 1, 1)
diff --git a/Misc/NEWS.d/next/Core and Builtins/2021-12-11-17-40-34.bpo-46042.aqYxku.rst b/Misc/NEWS.d/next/Core and Builtins/2021-12-11-17-40-34.bpo-46042.aqYxku.rst
new file mode 100644
index 00000000000000..7a302bcd7648b3
--- /dev/null
+++ b/Misc/NEWS.d/next/Core and Builtins/2021-12-11-17-40-34.bpo-46042.aqYxku.rst
@@ -0,0 +1,2 @@
+Improve the location of the caret in :exc:`SyntaxError` exceptions emitted
+by the symbol table. Patch by Pablo Galindo.
diff --git a/Python/symtable.c b/Python/symtable.c
index 62bd1e2ec48f8a..07f9d1132c797e 100644
--- a/Python/symtable.c
+++ b/Python/symtable.c
@@ -49,6 +49,12 @@
"'%s' can not be used within an annotation"
+#define LOCATION(x) \
+ (x)->lineno, (x)->col_offset, (x)->end_lineno, (x)->end_col_offset
+
+#define ST_LOCATION(x) \
+ (x)->ste_lineno, (x)->ste_col_offset, (x)->ste_end_lineno, (x)->ste_end_col_offset
+
static PySTEntryObject *
ste_new(struct symtable *st, identifier name, _Py_block_ty block,
void *key, int lineno, int col_offset,
@@ -96,7 +102,7 @@ ste_new(struct symtable *st, identifier name, _Py_block_ty block,
ste->ste_child_free = 0;
ste->ste_generator = 0;
ste->ste_coroutine = 0;
- ste->ste_comprehension = 0;
+ ste->ste_comprehension = NoComprehension;
ste->ste_returns_value = 0;
ste->ste_needs_class_closure = 0;
ste->ste_comp_iter_target = 0;
@@ -221,6 +227,7 @@ static int symtable_visit_withitem(struct symtable *st, withitem_ty item);
static int symtable_visit_match_case(struct symtable *st, match_case_ty m);
static int symtable_visit_pattern(struct symtable *st, pattern_ty s);
static int symtable_raise_if_annotation_block(struct symtable *st, const char *, expr_ty);
+static int symtable_raise_if_comprehension_block(struct symtable *st, expr_ty);
static identifier top = NULL, lambda = NULL, genexpr = NULL,
@@ -1024,7 +1031,8 @@ symtable_lookup(struct symtable *st, PyObject *name)
}
static int
-symtable_add_def_helper(struct symtable *st, PyObject *name, int flag, struct _symtable_entry *ste)
+symtable_add_def_helper(struct symtable *st, PyObject *name, int flag, struct _symtable_entry *ste,
+ int lineno, int col_offset, int end_lineno, int end_col_offset)
{
PyObject *o;
PyObject *dict;
@@ -1041,10 +1049,8 @@ symtable_add_def_helper(struct symtable *st, PyObject *name, int flag, struct _s
/* Is it better to use 'mangled' or 'name' here? */
PyErr_Format(PyExc_SyntaxError, DUPLICATE_ARGUMENT, name);
PyErr_RangedSyntaxLocationObject(st->st_filename,
- ste->ste_lineno,
- ste->ste_col_offset + 1,
- ste->ste_end_lineno,
- ste->ste_end_col_offset + 1);
+ lineno, col_offset + 1,
+ end_lineno, end_col_offset + 1);
goto error;
}
val |= flag;
@@ -1065,10 +1071,8 @@ symtable_add_def_helper(struct symtable *st, PyObject *name, int flag, struct _s
PyErr_Format(PyExc_SyntaxError,
NAMED_EXPR_COMP_INNER_LOOP_CONFLICT, name);
PyErr_RangedSyntaxLocationObject(st->st_filename,
- ste->ste_lineno,
- ste->ste_col_offset + 1,
- ste->ste_end_lineno,
- ste->ste_end_col_offset + 1);
+ lineno, col_offset + 1,
+ end_lineno, end_col_offset + 1);
goto error;
}
val |= DEF_COMP_ITER;
@@ -1113,8 +1117,11 @@ symtable_add_def_helper(struct symtable *st, PyObject *name, int flag, struct _s
}
static int
-symtable_add_def(struct symtable *st, PyObject *name, int flag) {
- return symtable_add_def_helper(st, name, flag, st->st_cur);
+symtable_add_def(struct symtable *st, PyObject *name, int flag,
+ int lineno, int col_offset, int end_lineno, int end_col_offset)
+{
+ return symtable_add_def_helper(st, name, flag, st->st_cur,
+ lineno, col_offset, end_lineno, end_col_offset);
}
/* VISIT, VISIT_SEQ and VIST_SEQ_TAIL take an ASDL type as their second argument.
@@ -1199,7 +1206,7 @@ symtable_visit_stmt(struct symtable *st, stmt_ty s)
}
switch (s->kind) {
case FunctionDef_kind:
- if (!symtable_add_def(st, s->v.FunctionDef.name, DEF_LOCAL))
+ if (!symtable_add_def(st, s->v.FunctionDef.name, DEF_LOCAL, LOCATION(s)))
VISIT_QUIT(st, 0);
if (s->v.FunctionDef.args->defaults)
VISIT_SEQ(st, expr, s->v.FunctionDef.args->defaults);
@@ -1212,8 +1219,7 @@ symtable_visit_stmt(struct symtable *st, stmt_ty s)
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,
- s->end_lineno, s->end_col_offset))
+ LOCATION(s)))
VISIT_QUIT(st, 0);
VISIT(st, arguments, s->v.FunctionDef.args);
VISIT_SEQ(st, stmt, s->v.FunctionDef.body);
@@ -1222,7 +1228,7 @@ symtable_visit_stmt(struct symtable *st, stmt_ty s)
break;
case ClassDef_kind: {
PyObject *tmp;
- if (!symtable_add_def(st, s->v.ClassDef.name, DEF_LOCAL))
+ if (!symtable_add_def(st, s->v.ClassDef.name, DEF_LOCAL, LOCATION(s)))
VISIT_QUIT(st, 0);
VISIT_SEQ(st, expr, s->v.ClassDef.bases);
VISIT_SEQ(st, keyword, s->v.ClassDef.keywords);
@@ -1275,12 +1281,12 @@ symtable_visit_stmt(struct symtable *st, stmt_ty s)
}
if (s->v.AnnAssign.simple &&
!symtable_add_def(st, e_name->v.Name.id,
- DEF_ANNOT | DEF_LOCAL)) {
+ DEF_ANNOT | DEF_LOCAL, LOCATION(e_name))) {
VISIT_QUIT(st, 0);
}
else {
if (s->v.AnnAssign.value
- && !symtable_add_def(st, e_name->v.Name.id, DEF_LOCAL)) {
+ && !symtable_add_def(st, e_name->v.Name.id, DEF_LOCAL, LOCATION(e_name))) {
VISIT_QUIT(st, 0);
}
}
@@ -1377,7 +1383,7 @@ symtable_visit_stmt(struct symtable *st, stmt_ty s)
s->end_col_offset + 1);
VISIT_QUIT(st, 0);
}
- if (!symtable_add_def(st, name, DEF_GLOBAL))
+ if (!symtable_add_def(st, name, DEF_GLOBAL, LOCATION(s)))
VISIT_QUIT(st, 0);
if (!symtable_record_directive(st, name, s->lineno, s->col_offset,
s->end_lineno, s->end_col_offset))
@@ -1412,7 +1418,7 @@ symtable_visit_stmt(struct symtable *st, stmt_ty s)
s->end_col_offset + 1);
VISIT_QUIT(st, 0);
}
- if (!symtable_add_def(st, name, DEF_NONLOCAL))
+ if (!symtable_add_def(st, name, DEF_NONLOCAL, LOCATION(s)))
VISIT_QUIT(st, 0);
if (!symtable_record_directive(st, name, s->lineno, s->col_offset,
s->end_lineno, s->end_col_offset))
@@ -1433,7 +1439,7 @@ symtable_visit_stmt(struct symtable *st, stmt_ty s)
VISIT_SEQ(st, stmt, s->v.With.body);
break;
case AsyncFunctionDef_kind:
- if (!symtable_add_def(st, s->v.AsyncFunctionDef.name, DEF_LOCAL))
+ if (!symtable_add_def(st, s->v.AsyncFunctionDef.name, DEF_LOCAL, LOCATION(s)))
VISIT_QUIT(st, 0);
if (s->v.AsyncFunctionDef.args->defaults)
VISIT_SEQ(st, expr, s->v.AsyncFunctionDef.args->defaults);
@@ -1508,27 +1514,25 @@ symtable_extend_namedexpr_scope(struct symtable *st, expr_ty e)
if (ste->ste_type == FunctionBlock) {
long target_in_scope = _PyST_GetSymbol(ste, target_name);
if (target_in_scope & DEF_GLOBAL) {
- if (!symtable_add_def(st, target_name, DEF_GLOBAL))
+ if (!symtable_add_def(st, target_name, DEF_GLOBAL, LOCATION(e)))
VISIT_QUIT(st, 0);
} else {
- if (!symtable_add_def(st, target_name, DEF_NONLOCAL))
+ if (!symtable_add_def(st, target_name, DEF_NONLOCAL, LOCATION(e)))
VISIT_QUIT(st, 0);
}
- if (!symtable_record_directive(st, target_name, e->lineno, e->col_offset,
- e->end_lineno, e->end_col_offset))
+ if (!symtable_record_directive(st, target_name, LOCATION(e)))
VISIT_QUIT(st, 0);
- return symtable_add_def_helper(st, target_name, DEF_LOCAL, ste);
+ return symtable_add_def_helper(st, target_name, DEF_LOCAL, ste, LOCATION(e));
}
/* If we find a ModuleBlock entry, add as GLOBAL */
if (ste->ste_type == ModuleBlock) {
- if (!symtable_add_def(st, target_name, DEF_GLOBAL))
+ if (!symtable_add_def(st, target_name, DEF_GLOBAL, LOCATION(e)))
VISIT_QUIT(st, 0);
- if (!symtable_record_directive(st, target_name, e->lineno, e->col_offset,
- e->end_lineno, e->end_col_offset))
+ if (!symtable_record_directive(st, target_name, LOCATION(e)))
VISIT_QUIT(st, 0);
- return symtable_add_def_helper(st, target_name, DEF_GLOBAL, ste);
+ return symtable_add_def_helper(st, target_name, DEF_GLOBAL, ste, LOCATION(e));
}
/* Disallow usage in ClassBlock */
if (ste->ste_type == ClassBlock) {
@@ -1651,6 +1655,9 @@ symtable_visit_expr(struct symtable *st, expr_ty e)
if (e->v.Yield.value)
VISIT(st, expr, e->v.Yield.value);
st->st_cur->ste_generator = 1;
+ if (st->st_cur->ste_comprehension) {
+ return symtable_raise_if_comprehension_block(st, e);
+ }
break;
case YieldFrom_kind:
if (!symtable_raise_if_annotation_block(st, "yield expression", e)) {
@@ -1658,6 +1665,9 @@ symtable_visit_expr(struct symtable *st, expr_ty e)
}
VISIT(st, expr, e->v.YieldFrom.value);
st->st_cur->ste_generator = 1;
+ if (st->st_cur->ste_comprehension) {
+ return symtable_raise_if_comprehension_block(st, e);
+ }
break;
case Await_kind:
if (!symtable_raise_if_annotation_block(st, "await expression", e)) {
@@ -1707,14 +1717,14 @@ symtable_visit_expr(struct symtable *st, expr_ty e)
break;
case Name_kind:
if (!symtable_add_def(st, e->v.Name.id,
- e->v.Name.ctx == Load ? USE : DEF_LOCAL))
+ e->v.Name.ctx == Load ? USE : DEF_LOCAL, LOCATION(e)))
VISIT_QUIT(st, 0);
/* Special-case super: it counts as a use of __class__ */
if (e->v.Name.ctx == Load &&
st->st_cur->ste_type == FunctionBlock &&
_PyUnicode_EqualToASCIIString(e->v.Name.id, "super")) {
if (!GET_IDENTIFIER(__class__) ||
- !symtable_add_def(st, __class__, USE))
+ !symtable_add_def(st, __class__, USE, LOCATION(e)))
VISIT_QUIT(st, 0);
}
break;
@@ -1749,14 +1759,14 @@ symtable_visit_pattern(struct symtable *st, pattern_ty p)
break;
case MatchStar_kind:
if (p->v.MatchStar.name) {
- symtable_add_def(st, p->v.MatchStar.name, DEF_LOCAL);
+ symtable_add_def(st, p->v.MatchStar.name, DEF_LOCAL, LOCATION(p));
}
break;
case MatchMapping_kind:
VISIT_SEQ(st, expr, p->v.MatchMapping.keys);
VISIT_SEQ(st, pattern, p->v.MatchMapping.patterns);
if (p->v.MatchMapping.rest) {
- symtable_add_def(st, p->v.MatchMapping.rest, DEF_LOCAL);
+ symtable_add_def(st, p->v.MatchMapping.rest, DEF_LOCAL, LOCATION(p));
}
break;
case MatchClass_kind:
@@ -1769,7 +1779,7 @@ symtable_visit_pattern(struct symtable *st, pattern_ty p)
VISIT(st, pattern, p->v.MatchAs.pattern);
}
if (p->v.MatchAs.name) {
- symtable_add_def(st, p->v.MatchAs.name, DEF_LOCAL);
+ symtable_add_def(st, p->v.MatchAs.name, DEF_LOCAL, LOCATION(p));
}
break;
case MatchOr_kind:
@@ -1785,7 +1795,7 @@ symtable_implicit_arg(struct symtable *st, int pos)
PyObject *id = PyUnicode_FromFormat(".%d", pos);
if (id == NULL)
return 0;
- if (!symtable_add_def(st, id, DEF_PARAM)) {
+ if (!symtable_add_def(st, id, DEF_PARAM, ST_LOCATION(st->st_cur))) {
Py_DECREF(id);
return 0;
}
@@ -1803,7 +1813,7 @@ symtable_visit_params(struct symtable *st, asdl_arg_seq *args)
for (i = 0; i < asdl_seq_LEN(args); i++) {
arg_ty arg = (arg_ty)asdl_seq_GET(args, i);
- if (!symtable_add_def(st, arg->arg, DEF_PARAM))
+ if (!symtable_add_def(st, arg->arg, DEF_PARAM, LOCATION(arg)))
return 0;
}
@@ -1887,12 +1897,12 @@ symtable_visit_arguments(struct symtable *st, arguments_ty a)
if (a->kwonlyargs && !symtable_visit_params(st, a->kwonlyargs))
return 0;
if (a->vararg) {
- if (!symtable_add_def(st, a->vararg->arg, DEF_PARAM))
+ if (!symtable_add_def(st, a->vararg->arg, DEF_PARAM, LOCATION(a->vararg)))
return 0;
st->st_cur->ste_varargs = 1;
}
if (a->kwarg) {
- if (!symtable_add_def(st, a->kwarg->arg, DEF_PARAM))
+ if (!symtable_add_def(st, a->kwarg->arg, DEF_PARAM, LOCATION(a->kwarg)))
return 0;
st->st_cur->ste_varkeywords = 1;
}
@@ -1906,7 +1916,7 @@ symtable_visit_excepthandler(struct symtable *st, excepthandler_ty eh)
if (eh->v.ExceptHandler.type)
VISIT(st, expr, eh->v.ExceptHandler.type);
if (eh->v.ExceptHandler.name)
- if (!symtable_add_def(st, eh->v.ExceptHandler.name, DEF_LOCAL))
+ if (!symtable_add_def(st, eh->v.ExceptHandler.name, DEF_LOCAL, LOCATION(eh)))
return 0;
VISIT_SEQ(st, stmt, eh->v.ExceptHandler.body);
return 1;
@@ -1954,16 +1964,16 @@ symtable_visit_alias(struct symtable *st, alias_ty a)
Py_INCREF(store_name);
}
if (!_PyUnicode_EqualToASCIIString(name, "*")) {
- int r = symtable_add_def(st, store_name, DEF_IMPORT);
+ int r = symtable_add_def(st, store_name, DEF_IMPORT, LOCATION(a));
Py_DECREF(store_name);
return r;
}
else {
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;
+ int lineno = a->lineno;
+ int col_offset = a->col_offset;
+ int end_lineno = a->end_lineno;
+ int end_col_offset = a->end_col_offset;
PyErr_SetString(PyExc_SyntaxError, IMPORT_STAR_WARNING);
PyErr_RangedSyntaxLocationObject(st->st_filename,
lineno, col_offset + 1,
@@ -2021,10 +2031,23 @@ symtable_handle_comprehension(struct symtable *st, expr_ty e,
e->end_lineno, e->end_col_offset)) {
return 0;
}
+ switch(e->kind) {
+ case ListComp_kind:
+ st->st_cur->ste_comprehension = ListComprehension;
+ break;
+ case SetComp_kind:
+ st->st_cur->ste_comprehension = SetComprehension;
+ break;
+ case DictComp_kind:
+ st->st_cur->ste_comprehension = DictComprehension;
+ break;
+ default:
+ st->st_cur->ste_comprehension = GeneratorExpression;
+ break;
+ }
if (outermost->is_async) {
st->st_cur->ste_coroutine = 1;
}
- st->st_cur->ste_comprehension = 1;
/* Outermost iter is received as an argument */
if (!symtable_implicit_arg(st, 0)) {
@@ -2041,20 +2064,6 @@ symtable_handle_comprehension(struct symtable *st, expr_ty e,
if (value)
VISIT(st, expr, value);
VISIT(st, expr, elt);
- if (st->st_cur->ste_generator) {
- PyErr_SetString(PyExc_SyntaxError,
- (e->kind == ListComp_kind) ? "'yield' inside list comprehension" :
- (e->kind == SetComp_kind) ? "'yield' inside set comprehension" :
- (e->kind == DictComp_kind) ? "'yield' inside dict comprehension" :
- "'yield' inside generator expression");
- 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;
- }
st->st_cur->ste_generator = is_generator;
return symtable_exit_block(st);
}
@@ -2108,6 +2117,20 @@ symtable_raise_if_annotation_block(struct symtable *st, const char *name, expr_t
return 0;
}
+static int
+symtable_raise_if_comprehension_block(struct symtable *st, expr_ty e) {
+ _Py_comprehension_ty type = st->st_cur->ste_comprehension;
+ PyErr_SetString(PyExc_SyntaxError,
+ (type == ListComprehension) ? "'yield' inside list comprehension" :
+ (type == SetComprehension) ? "'yield' inside set comprehension" :
+ (type == DictComprehension) ? "'yield' inside dict comprehension" :
+ "'yield' inside generator expression");
+ PyErr_RangedSyntaxLocationObject(st->st_filename,
+ e->lineno, e->col_offset + 1,
+ e->end_lineno, e->end_col_offset + 1);
+ VISIT_QUIT(st, 0);
+}
+
struct symtable *
_Py_SymtableStringObjectFlags(const char *str, PyObject *filename,
int start, PyCompilerFlags *flags)