From 445c7fd4b7e5bb4ea78b445968a893a566538914 Mon Sep 17 00:00:00 2001 From: Pablo Galindo Date: Wed, 13 May 2020 23:22:43 +0100 Subject: [PATCH 1/9] bpo-40334: Correctly identify invalid target in assignment errors --- Grammar/python.gram | 5 ++++- Lib/test/test_foo.py | 16 ++++++++++++++++ Lib/test/test_syntax.py | 25 ++++++++++++------------- Parser/pegen/parse.c | 2 +- Parser/pegen/pegen.c | 39 +++++++++++++++++++++++++++++++++++++++ Parser/pegen/pegen.h | 5 +++++ 6 files changed, 77 insertions(+), 15 deletions(-) create mode 100644 Lib/test/test_foo.py diff --git a/Grammar/python.gram b/Grammar/python.gram index 9087c7aa718b17..bbaf4600a0b3a1 100644 --- a/Grammar/python.gram +++ b/Grammar/python.gram @@ -641,7 +641,10 @@ invalid_assignment: | a=expression ':' expression ['=' annotated_rhs] { RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, "illegal target for annotation") } | a=expression ('=' | augassign) (yield_expr | star_expressions) { - RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, "cannot assign to %s", _PyPegen_get_expr_name(a)) } + RAISE_SYNTAX_ERROR_KNOWN_LOCATION( + _PyPegen_get_invalid_target(a), + "cannot assign to %s", _PyPegen_get_expr_name(_PyPegen_get_invalid_target(a)) + )} invalid_block: | NEWLINE !INDENT { RAISE_INDENTATION_ERROR("expected an indented block") } invalid_comprehension: diff --git a/Lib/test/test_foo.py b/Lib/test/test_foo.py new file mode 100644 index 00000000000000..32e0e1a5c8f0b0 --- /dev/null +++ b/Lib/test/test_foo.py @@ -0,0 +1,16 @@ +import unittest +import zoneinfo +import tracemalloc + +class Test(unittest.TestCase): + def test_foo(self): + # snapshot1 = tracemalloc.take_snapshot() + zoneinfo.ZoneInfo.no_cache("America/Los_Angeles") + # snapshot2 = tracemalloc.take_snapshot() + # top_stats = snapshot2.compare_to(snapshot1, 'lineno') + + # print("[ Top 10 differences ]") + # for stat in top_stats[:10]: + # print(stat) + + diff --git a/Lib/test/test_syntax.py b/Lib/test/test_syntax.py index a3a101534628a2..51a5f42416ccea 100644 --- a/Lib/test/test_syntax.py +++ b/Lib/test/test_syntax.py @@ -100,30 +100,29 @@ This test just checks a couple of cases rather than enumerating all of them. -# All of the following also produce different error messages with pegen -# >>> (a, "b", c) = (1, 2, 3) -# Traceback (most recent call last): -# SyntaxError: cannot assign to literal +>>> (a, "b", c) = (1, 2, 3) +Traceback (most recent call last): +SyntaxError: cannot assign to literal -# >>> (a, True, c) = (1, 2, 3) -# Traceback (most recent call last): -# SyntaxError: cannot assign to True +>>> (a, True, c) = (1, 2, 3) +Traceback (most recent call last): +SyntaxError: cannot assign to True >>> (a, __debug__, c) = (1, 2, 3) Traceback (most recent call last): SyntaxError: cannot assign to __debug__ -# >>> (a, *True, c) = (1, 2, 3) -# Traceback (most recent call last): -# SyntaxError: cannot assign to True +>>> (a, *True, c) = (1, 2, 3) +Traceback (most recent call last): +SyntaxError: cannot assign to True >>> (a, *__debug__, c) = (1, 2, 3) Traceback (most recent call last): SyntaxError: cannot assign to __debug__ -# >>> [a, b, c + 1] = [1, 2, 3] -# Traceback (most recent call last): -# SyntaxError: cannot assign to operator +>>> [a, b, c + 1] = [1, 2, 3] +Traceback (most recent call last): +SyntaxError: cannot assign to operator >>> a if 1 else b = 1 Traceback (most recent call last): diff --git a/Parser/pegen/parse.c b/Parser/pegen/parse.c index 851d17226d162f..10b966db066ead 100644 --- a/Parser/pegen/parse.c +++ b/Parser/pegen/parse.c @@ -10853,7 +10853,7 @@ invalid_assignment_rule(Parser *p) (_tmp_129_var = _tmp_129_rule(p)) // yield_expr | star_expressions ) { - _res = RAISE_SYNTAX_ERROR_KNOWN_LOCATION ( a , "cannot assign to %s" , _PyPegen_get_expr_name ( a ) ); + _res = RAISE_SYNTAX_ERROR_KNOWN_LOCATION ( _PyPegen_get_invalid_target ( a ) , "cannot assign to %s" , _PyPegen_get_expr_name ( _PyPegen_get_invalid_target ( a ) ) ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; return NULL; diff --git a/Parser/pegen/pegen.c b/Parser/pegen/pegen.c index 8b79a7364758e4..d1e51a9429073a 100644 --- a/Parser/pegen/pegen.c +++ b/Parser/pegen/pegen.c @@ -2054,3 +2054,42 @@ _PyPegen_make_module(Parser *p, asdl_seq *a) { } return Module(a, type_ignores, p->arena); } + +// Error reporting helpers + +expr_ty +_PyPegen_get_invalid_target(expr_ty e) +{ + if (e == NULL) { + return NULL; + } + switch (e->kind) { + case List_kind: { + Py_ssize_t len = asdl_seq_LEN(e->v.List.elts); + for (Py_ssize_t i = 0; i < len; i++) { + expr_ty other = asdl_seq_GET(e->v.List.elts, i); + if (_PyPegen_get_invalid_target(other)) { + return other; + } + } + return NULL; + } + case Tuple_kind: { + Py_ssize_t len = asdl_seq_LEN(e->v.Tuple.elts); + for (Py_ssize_t i = 0; i < len; i++) { + expr_ty other = asdl_seq_GET(e->v.Tuple.elts, i); + expr_ty child = _PyPegen_get_invalid_target(other); + if (child != NULL) { + return child; + } + } + return NULL; + } + case Starred_kind: + return _PyPegen_get_invalid_target(e->v.Starred.value); + case Name_kind: + return NULL; + default: + return e; + } +} \ No newline at end of file diff --git a/Parser/pegen/pegen.h b/Parser/pegen/pegen.h index e5b1b757bd894b..964b5599f3d644 100644 --- a/Parser/pegen/pegen.h +++ b/Parser/pegen/pegen.h @@ -260,6 +260,11 @@ void *_PyPegen_arguments_parsing_error(Parser *, expr_ty); int _PyPegen_check_barry_as_flufl(Parser *); mod_ty _PyPegen_make_module(Parser *, asdl_seq *); +// Error reporting helpers + +expr_ty _PyPegen_get_invalid_target(expr_ty e); + + void *_PyPegen_parse(Parser *); #endif From d385c2928d57cac20052b71261278a46487d4b2c Mon Sep 17 00:00:00 2001 From: Pablo Galindo Date: Thu, 14 May 2020 00:12:53 +0100 Subject: [PATCH 2/9] Update Grammar/python.gram Co-authored-by: Lysandros Nikolaou --- Grammar/python.gram | 12 +- Lib/test/test_foo.py | 16 --- Lib/test/test_syntax.py | 8 ++ Parser/pegen/parse.c | 308 +++++++++++++++++++++++++--------------- Parser/pegen/pegen.c | 7 +- 5 files changed, 219 insertions(+), 132 deletions(-) delete mode 100644 Lib/test/test_foo.py diff --git a/Grammar/python.gram b/Grammar/python.gram index bbaf4600a0b3a1..a2e82f3ef82d75 100644 --- a/Grammar/python.gram +++ b/Grammar/python.gram @@ -640,11 +640,21 @@ invalid_assignment: RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, "only single target (not tuple) can be annotated") } | a=expression ':' expression ['=' annotated_rhs] { RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, "illegal target for annotation") } - | a=expression ('=' | augassign) (yield_expr | star_expressions) { + | a=star_expressions '=' (yield_expr | star_expressions) { RAISE_SYNTAX_ERROR_KNOWN_LOCATION( _PyPegen_get_invalid_target(a), "cannot assign to %s", _PyPegen_get_expr_name(_PyPegen_get_invalid_target(a)) )} + | a=expression augassign (yield_expr | star_expressions) { + RAISE_SYNTAX_ERROR_KNOWN_LOCATION( + _PyPegen_get_invalid_target(a), + "cannot assign to %s", _PyPegen_get_expr_name(_PyPegen_get_invalid_target(a)) + )} + | a=star_expressions augassign (yield_expr | star_expressions) { + RAISE_SYNTAX_ERROR_KNOWN_LOCATION( + a, + "illegal expression for augmented assignment" + )} invalid_block: | NEWLINE !INDENT { RAISE_INDENTATION_ERROR("expected an indented block") } invalid_comprehension: diff --git a/Lib/test/test_foo.py b/Lib/test/test_foo.py deleted file mode 100644 index 32e0e1a5c8f0b0..00000000000000 --- a/Lib/test/test_foo.py +++ /dev/null @@ -1,16 +0,0 @@ -import unittest -import zoneinfo -import tracemalloc - -class Test(unittest.TestCase): - def test_foo(self): - # snapshot1 = tracemalloc.take_snapshot() - zoneinfo.ZoneInfo.no_cache("America/Los_Angeles") - # snapshot2 = tracemalloc.take_snapshot() - # top_stats = snapshot2.compare_to(snapshot1, 'lineno') - - # print("[ Top 10 differences ]") - # for stat in top_stats[:10]: - # print(stat) - - diff --git a/Lib/test/test_syntax.py b/Lib/test/test_syntax.py index 51a5f42416ccea..258152dabed9cb 100644 --- a/Lib/test/test_syntax.py +++ b/Lib/test/test_syntax.py @@ -124,6 +124,14 @@ Traceback (most recent call last): SyntaxError: cannot assign to operator +>>> [a, b[1], c + 1] = [1, 2, 3] +Traceback (most recent call last): +SyntaxError: cannot assign to operator + +>>> [a, b.c.d, c + 1] = [1, 2, 3] +Traceback (most recent call last): +SyntaxError: cannot assign to operator + >>> a if 1 else b = 1 Traceback (most recent call last): SyntaxError: cannot assign to conditional expression diff --git a/Parser/pegen/parse.c b/Parser/pegen/parse.c index 10b966db066ead..a068d047d314c7 100644 --- a/Parser/pegen/parse.c +++ b/Parser/pegen/parse.c @@ -351,8 +351,8 @@ static KeywordToken *reserved_keywords[] = { #define _tmp_128_type 1280 #define _tmp_129_type 1281 #define _tmp_130_type 1282 -#define _loop0_131_type 1283 -#define _tmp_132_type 1284 +#define _tmp_131_type 1283 +#define _loop0_132_type 1284 #define _tmp_133_type 1285 #define _tmp_134_type 1286 #define _tmp_135_type 1287 @@ -366,9 +366,10 @@ static KeywordToken *reserved_keywords[] = { #define _tmp_143_type 1295 #define _tmp_144_type 1296 #define _tmp_145_type 1297 -#define _loop1_146_type 1298 -#define _tmp_147_type 1299 +#define _tmp_146_type 1298 +#define _loop1_147_type 1299 #define _tmp_148_type 1300 +#define _tmp_149_type 1301 static mod_ty file_rule(Parser *p); static mod_ty interactive_rule(Parser *p); @@ -653,8 +654,8 @@ static void *_tmp_127_rule(Parser *p); static void *_tmp_128_rule(Parser *p); static void *_tmp_129_rule(Parser *p); static void *_tmp_130_rule(Parser *p); -static asdl_seq *_loop0_131_rule(Parser *p); -static void *_tmp_132_rule(Parser *p); +static void *_tmp_131_rule(Parser *p); +static asdl_seq *_loop0_132_rule(Parser *p); static void *_tmp_133_rule(Parser *p); static void *_tmp_134_rule(Parser *p); static void *_tmp_135_rule(Parser *p); @@ -668,9 +669,10 @@ static void *_tmp_142_rule(Parser *p); static void *_tmp_143_rule(Parser *p); static void *_tmp_144_rule(Parser *p); static void *_tmp_145_rule(Parser *p); -static asdl_seq *_loop1_146_rule(Parser *p); -static void *_tmp_147_rule(Parser *p); +static void *_tmp_146_rule(Parser *p); +static asdl_seq *_loop1_147_rule(Parser *p); static void *_tmp_148_rule(Parser *p); +static void *_tmp_149_rule(Parser *p); // file: statements? $ @@ -10747,7 +10749,9 @@ invalid_named_expression_rule(Parser *p) // | tuple ':' // | star_named_expression ',' star_named_expressions* ':' // | expression ':' expression ['=' annotated_rhs] -// | expression ('=' | augassign) (yield_expr | star_expressions) +// | star_expressions '=' (yield_expr | star_expressions) +// | expression augassign (yield_expr | star_expressions) +// | star_expressions augassign (yield_expr | star_expressions) static void * invalid_assignment_rule(Parser *p) { @@ -10841,14 +10845,35 @@ invalid_assignment_rule(Parser *p) } p->mark = _mark; } - { // expression ('=' | augassign) (yield_expr | star_expressions) + { // star_expressions '=' (yield_expr | star_expressions) + Token * _literal; void *_tmp_128_var; + expr_ty a; + if ( + (a = star_expressions_rule(p)) // star_expressions + && + (_literal = _PyPegen_expect_token(p, 22)) // token='=' + && + (_tmp_128_var = _tmp_128_rule(p)) // yield_expr | star_expressions + ) + { + _res = RAISE_SYNTAX_ERROR_KNOWN_LOCATION ( _PyPegen_get_invalid_target ( a ) , "cannot assign to %s" , _PyPegen_get_expr_name ( _PyPegen_get_invalid_target ( a ) ) ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + return NULL; + } + goto done; + } + p->mark = _mark; + } + { // expression augassign (yield_expr | star_expressions) void *_tmp_129_var; expr_ty a; + AugOperator* augassign_var; if ( (a = expression_rule(p)) // expression && - (_tmp_128_var = _tmp_128_rule(p)) // '=' | augassign + (augassign_var = augassign_rule(p)) // augassign && (_tmp_129_var = _tmp_129_rule(p)) // yield_expr | star_expressions ) @@ -10862,6 +10887,27 @@ invalid_assignment_rule(Parser *p) } p->mark = _mark; } + { // star_expressions augassign (yield_expr | star_expressions) + void *_tmp_130_var; + expr_ty a; + AugOperator* augassign_var; + if ( + (a = star_expressions_rule(p)) // star_expressions + && + (augassign_var = augassign_rule(p)) // augassign + && + (_tmp_130_var = _tmp_130_rule(p)) // yield_expr | star_expressions + ) + { + _res = RAISE_SYNTAX_ERROR_KNOWN_LOCATION ( a , "illegal expression for augmented assignment" ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + return NULL; + } + goto done; + } + p->mark = _mark; + } _res = NULL; done: return _res; @@ -10908,11 +10954,11 @@ invalid_comprehension_rule(Parser *p) void * _res = NULL; int _mark = p->mark; { // ('[' | '(' | '{') starred_expression for_if_clauses - void *_tmp_130_var; + void *_tmp_131_var; expr_ty a; asdl_seq* for_if_clauses_var; if ( - (_tmp_130_var = _tmp_130_rule(p)) // '[' | '(' | '{' + (_tmp_131_var = _tmp_131_rule(p)) // '[' | '(' | '{' && (a = starred_expression_rule(p)) // starred_expression && @@ -10944,13 +10990,13 @@ invalid_parameters_rule(Parser *p) void * _res = NULL; int _mark = p->mark; { // param_no_default* (slash_with_default | param_with_default+) param_no_default - asdl_seq * _loop0_131_var; - void *_tmp_132_var; + asdl_seq * _loop0_132_var; + void *_tmp_133_var; arg_ty param_no_default_var; if ( - (_loop0_131_var = _loop0_131_rule(p)) // param_no_default* + (_loop0_132_var = _loop0_132_rule(p)) // param_no_default* && - (_tmp_132_var = _tmp_132_rule(p)) // slash_with_default | param_with_default+ + (_tmp_133_var = _tmp_133_rule(p)) // slash_with_default | param_with_default+ && (param_no_default_var = param_no_default_rule(p)) // param_no_default ) @@ -10980,11 +11026,11 @@ invalid_star_etc_rule(Parser *p) int _mark = p->mark; { // '*' (')' | ',' (')' | '**')) Token * _literal; - void *_tmp_133_var; + void *_tmp_134_var; if ( (_literal = _PyPegen_expect_token(p, 16)) // token='*' && - (_tmp_133_var = _tmp_133_rule(p)) // ')' | ',' (')' | '**') + (_tmp_134_var = _tmp_134_rule(p)) // ')' | ',' (')' | '**') ) { _res = RAISE_SYNTAX_ERROR ( "named arguments must follow bare *" ); @@ -11012,11 +11058,11 @@ invalid_lambda_star_etc_rule(Parser *p) int _mark = p->mark; { // '*' (':' | ',' (':' | '**')) Token * _literal; - void *_tmp_134_var; + void *_tmp_135_var; if ( (_literal = _PyPegen_expect_token(p, 16)) // token='*' && - (_tmp_134_var = _tmp_134_rule(p)) // ':' | ',' (':' | '**') + (_tmp_135_var = _tmp_135_rule(p)) // ':' | ',' (':' | '**') ) { _res = RAISE_SYNTAX_ERROR ( "named arguments must follow bare *" ); @@ -12000,12 +12046,12 @@ _loop1_22_rule(Parser *p) ssize_t _children_capacity = 1; ssize_t _n = 0; { // (star_targets '=') - void *_tmp_135_var; + void *_tmp_136_var; while ( - (_tmp_135_var = _tmp_135_rule(p)) // star_targets '=' + (_tmp_136_var = _tmp_136_rule(p)) // star_targets '=' ) { - _res = _tmp_135_var; + _res = _tmp_136_var; if (_n == _children_capacity) { _children_capacity *= 2; _children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); @@ -12327,12 +12373,12 @@ _loop0_30_rule(Parser *p) ssize_t _children_capacity = 1; ssize_t _n = 0; { // ('.' | '...') - void *_tmp_136_var; + void *_tmp_137_var; while ( - (_tmp_136_var = _tmp_136_rule(p)) // '.' | '...' + (_tmp_137_var = _tmp_137_rule(p)) // '.' | '...' ) { - _res = _tmp_136_var; + _res = _tmp_137_var; if (_n == _children_capacity) { _children_capacity *= 2; _children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); @@ -12376,12 +12422,12 @@ _loop1_31_rule(Parser *p) ssize_t _children_capacity = 1; ssize_t _n = 0; { // ('.' | '...') - void *_tmp_137_var; + void *_tmp_138_var; while ( - (_tmp_137_var = _tmp_137_rule(p)) // '.' | '...' + (_tmp_138_var = _tmp_138_rule(p)) // '.' | '...' ) { - _res = _tmp_137_var; + _res = _tmp_138_var; if (_n == _children_capacity) { _children_capacity *= 2; _children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); @@ -13958,12 +14004,12 @@ _loop1_67_rule(Parser *p) ssize_t _children_capacity = 1; ssize_t _n = 0; { // ('@' named_expression NEWLINE) - void *_tmp_138_var; + void *_tmp_139_var; while ( - (_tmp_138_var = _tmp_138_rule(p)) // '@' named_expression NEWLINE + (_tmp_139_var = _tmp_139_rule(p)) // '@' named_expression NEWLINE ) { - _res = _tmp_138_var; + _res = _tmp_139_var; if (_n == _children_capacity) { _children_capacity *= 2; _children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); @@ -14131,12 +14177,12 @@ _loop1_71_rule(Parser *p) ssize_t _children_capacity = 1; ssize_t _n = 0; { // (',' star_expression) - void *_tmp_139_var; + void *_tmp_140_var; while ( - (_tmp_139_var = _tmp_139_rule(p)) // ',' star_expression + (_tmp_140_var = _tmp_140_rule(p)) // ',' star_expression ) { - _res = _tmp_139_var; + _res = _tmp_140_var; if (_n == _children_capacity) { _children_capacity *= 2; _children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); @@ -14269,12 +14315,12 @@ _loop1_74_rule(Parser *p) ssize_t _children_capacity = 1; ssize_t _n = 0; { // (',' expression) - void *_tmp_140_var; + void *_tmp_141_var; while ( - (_tmp_140_var = _tmp_140_rule(p)) // ',' expression + (_tmp_141_var = _tmp_141_rule(p)) // ',' expression ) { - _res = _tmp_140_var; + _res = _tmp_141_var; if (_n == _children_capacity) { _children_capacity *= 2; _children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); @@ -15036,12 +15082,12 @@ _loop1_89_rule(Parser *p) ssize_t _children_capacity = 1; ssize_t _n = 0; { // ('or' conjunction) - void *_tmp_141_var; + void *_tmp_142_var; while ( - (_tmp_141_var = _tmp_141_rule(p)) // 'or' conjunction + (_tmp_142_var = _tmp_142_rule(p)) // 'or' conjunction ) { - _res = _tmp_141_var; + _res = _tmp_142_var; if (_n == _children_capacity) { _children_capacity *= 2; _children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); @@ -15089,12 +15135,12 @@ _loop1_90_rule(Parser *p) ssize_t _children_capacity = 1; ssize_t _n = 0; { // ('and' inversion) - void *_tmp_142_var; + void *_tmp_143_var; while ( - (_tmp_142_var = _tmp_142_rule(p)) // 'and' inversion + (_tmp_143_var = _tmp_143_rule(p)) // 'and' inversion ) { - _res = _tmp_142_var; + _res = _tmp_143_var; if (_n == _children_capacity) { _children_capacity *= 2; _children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); @@ -15744,12 +15790,12 @@ _loop0_105_rule(Parser *p) ssize_t _children_capacity = 1; ssize_t _n = 0; { // ('if' disjunction) - void *_tmp_143_var; + void *_tmp_144_var; while ( - (_tmp_143_var = _tmp_143_rule(p)) // 'if' disjunction + (_tmp_144_var = _tmp_144_rule(p)) // 'if' disjunction ) { - _res = _tmp_143_var; + _res = _tmp_144_var; if (_n == _children_capacity) { _children_capacity *= 2; _children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); @@ -15793,12 +15839,12 @@ _loop0_106_rule(Parser *p) ssize_t _children_capacity = 1; ssize_t _n = 0; { // ('if' disjunction) - void *_tmp_144_var; + void *_tmp_145_var; while ( - (_tmp_144_var = _tmp_144_rule(p)) // 'if' disjunction + (_tmp_145_var = _tmp_145_rule(p)) // 'if' disjunction ) { - _res = _tmp_144_var; + _res = _tmp_145_var; if (_n == _children_capacity) { _children_capacity *= 2; _children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); @@ -16246,12 +16292,12 @@ _loop0_117_rule(Parser *p) ssize_t _children_capacity = 1; ssize_t _n = 0; { // (',' star_target) - void *_tmp_145_var; + void *_tmp_146_var; while ( - (_tmp_145_var = _tmp_145_rule(p)) // ',' star_target + (_tmp_146_var = _tmp_146_rule(p)) // ',' star_target ) { - _res = _tmp_145_var; + _res = _tmp_146_var; if (_n == _children_capacity) { _children_capacity *= 2; _children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); @@ -16675,7 +16721,7 @@ _tmp_127_rule(Parser *p) return _res; } -// _tmp_128: '=' | augassign +// _tmp_128: yield_expr | star_expressions static void * _tmp_128_rule(Parser *p) { @@ -16684,24 +16730,24 @@ _tmp_128_rule(Parser *p) } void * _res = NULL; int _mark = p->mark; - { // '=' - Token * _literal; + { // yield_expr + expr_ty yield_expr_var; if ( - (_literal = _PyPegen_expect_token(p, 22)) // token='=' + (yield_expr_var = yield_expr_rule(p)) // yield_expr ) { - _res = _literal; + _res = yield_expr_var; goto done; } p->mark = _mark; } - { // augassign - AugOperator* augassign_var; + { // star_expressions + expr_ty star_expressions_var; if ( - (augassign_var = augassign_rule(p)) // augassign + (star_expressions_var = star_expressions_rule(p)) // star_expressions ) { - _res = augassign_var; + _res = star_expressions_var; goto done; } p->mark = _mark; @@ -16747,9 +16793,45 @@ _tmp_129_rule(Parser *p) return _res; } -// _tmp_130: '[' | '(' | '{' +// _tmp_130: yield_expr | star_expressions static void * _tmp_130_rule(Parser *p) +{ + if (p->error_indicator) { + return NULL; + } + void * _res = NULL; + int _mark = p->mark; + { // yield_expr + expr_ty yield_expr_var; + if ( + (yield_expr_var = yield_expr_rule(p)) // yield_expr + ) + { + _res = yield_expr_var; + goto done; + } + p->mark = _mark; + } + { // star_expressions + expr_ty star_expressions_var; + if ( + (star_expressions_var = star_expressions_rule(p)) // star_expressions + ) + { + _res = star_expressions_var; + goto done; + } + p->mark = _mark; + } + _res = NULL; + done: + return _res; +} + +// _tmp_131: '[' | '(' | '{' +static void * +_tmp_131_rule(Parser *p) { if (p->error_indicator) { return NULL; @@ -16794,9 +16876,9 @@ _tmp_130_rule(Parser *p) return _res; } -// _loop0_131: param_no_default +// _loop0_132: param_no_default static asdl_seq * -_loop0_131_rule(Parser *p) +_loop0_132_rule(Parser *p) { if (p->error_indicator) { return NULL; @@ -16833,19 +16915,19 @@ _loop0_131_rule(Parser *p) } asdl_seq *_seq = _Py_asdl_seq_new(_n, p->arena); if (!_seq) { - PyErr_Format(PyExc_MemoryError, "asdl_seq_new _loop0_131"); + PyErr_Format(PyExc_MemoryError, "asdl_seq_new _loop0_132"); PyMem_Free(_children); return NULL; } for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_131_type, _seq); + _PyPegen_insert_memo(p, _start_mark, _loop0_132_type, _seq); return _seq; } -// _tmp_132: slash_with_default | param_with_default+ +// _tmp_133: slash_with_default | param_with_default+ static void * -_tmp_132_rule(Parser *p) +_tmp_133_rule(Parser *p) { if (p->error_indicator) { return NULL; @@ -16864,12 +16946,12 @@ _tmp_132_rule(Parser *p) p->mark = _mark; } { // param_with_default+ - asdl_seq * _loop1_146_var; + asdl_seq * _loop1_147_var; if ( - (_loop1_146_var = _loop1_146_rule(p)) // param_with_default+ + (_loop1_147_var = _loop1_147_rule(p)) // param_with_default+ ) { - _res = _loop1_146_var; + _res = _loop1_147_var; goto done; } p->mark = _mark; @@ -16879,9 +16961,9 @@ _tmp_132_rule(Parser *p) return _res; } -// _tmp_133: ')' | ',' (')' | '**') +// _tmp_134: ')' | ',' (')' | '**') static void * -_tmp_133_rule(Parser *p) +_tmp_134_rule(Parser *p) { if (p->error_indicator) { return NULL; @@ -16901,14 +16983,14 @@ _tmp_133_rule(Parser *p) } { // ',' (')' | '**') Token * _literal; - void *_tmp_147_var; + void *_tmp_148_var; if ( (_literal = _PyPegen_expect_token(p, 12)) // token=',' && - (_tmp_147_var = _tmp_147_rule(p)) // ')' | '**' + (_tmp_148_var = _tmp_148_rule(p)) // ')' | '**' ) { - _res = _PyPegen_dummy_name(p, _literal, _tmp_147_var); + _res = _PyPegen_dummy_name(p, _literal, _tmp_148_var); goto done; } p->mark = _mark; @@ -16918,9 +17000,9 @@ _tmp_133_rule(Parser *p) return _res; } -// _tmp_134: ':' | ',' (':' | '**') +// _tmp_135: ':' | ',' (':' | '**') static void * -_tmp_134_rule(Parser *p) +_tmp_135_rule(Parser *p) { if (p->error_indicator) { return NULL; @@ -16940,14 +17022,14 @@ _tmp_134_rule(Parser *p) } { // ',' (':' | '**') Token * _literal; - void *_tmp_148_var; + void *_tmp_149_var; if ( (_literal = _PyPegen_expect_token(p, 12)) // token=',' && - (_tmp_148_var = _tmp_148_rule(p)) // ':' | '**' + (_tmp_149_var = _tmp_149_rule(p)) // ':' | '**' ) { - _res = _PyPegen_dummy_name(p, _literal, _tmp_148_var); + _res = _PyPegen_dummy_name(p, _literal, _tmp_149_var); goto done; } p->mark = _mark; @@ -16957,9 +17039,9 @@ _tmp_134_rule(Parser *p) return _res; } -// _tmp_135: star_targets '=' +// _tmp_136: star_targets '=' static void * -_tmp_135_rule(Parser *p) +_tmp_136_rule(Parser *p) { if (p->error_indicator) { return NULL; @@ -16989,9 +17071,9 @@ _tmp_135_rule(Parser *p) return _res; } -// _tmp_136: '.' | '...' +// _tmp_137: '.' | '...' static void * -_tmp_136_rule(Parser *p) +_tmp_137_rule(Parser *p) { if (p->error_indicator) { return NULL; @@ -17025,9 +17107,9 @@ _tmp_136_rule(Parser *p) return _res; } -// _tmp_137: '.' | '...' +// _tmp_138: '.' | '...' static void * -_tmp_137_rule(Parser *p) +_tmp_138_rule(Parser *p) { if (p->error_indicator) { return NULL; @@ -17061,9 +17143,9 @@ _tmp_137_rule(Parser *p) return _res; } -// _tmp_138: '@' named_expression NEWLINE +// _tmp_139: '@' named_expression NEWLINE static void * -_tmp_138_rule(Parser *p) +_tmp_139_rule(Parser *p) { if (p->error_indicator) { return NULL; @@ -17096,9 +17178,9 @@ _tmp_138_rule(Parser *p) return _res; } -// _tmp_139: ',' star_expression +// _tmp_140: ',' star_expression static void * -_tmp_139_rule(Parser *p) +_tmp_140_rule(Parser *p) { if (p->error_indicator) { return NULL; @@ -17128,9 +17210,9 @@ _tmp_139_rule(Parser *p) return _res; } -// _tmp_140: ',' expression +// _tmp_141: ',' expression static void * -_tmp_140_rule(Parser *p) +_tmp_141_rule(Parser *p) { if (p->error_indicator) { return NULL; @@ -17160,9 +17242,9 @@ _tmp_140_rule(Parser *p) return _res; } -// _tmp_141: 'or' conjunction +// _tmp_142: 'or' conjunction static void * -_tmp_141_rule(Parser *p) +_tmp_142_rule(Parser *p) { if (p->error_indicator) { return NULL; @@ -17192,9 +17274,9 @@ _tmp_141_rule(Parser *p) return _res; } -// _tmp_142: 'and' inversion +// _tmp_143: 'and' inversion static void * -_tmp_142_rule(Parser *p) +_tmp_143_rule(Parser *p) { if (p->error_indicator) { return NULL; @@ -17224,9 +17306,9 @@ _tmp_142_rule(Parser *p) return _res; } -// _tmp_143: 'if' disjunction +// _tmp_144: 'if' disjunction static void * -_tmp_143_rule(Parser *p) +_tmp_144_rule(Parser *p) { if (p->error_indicator) { return NULL; @@ -17256,9 +17338,9 @@ _tmp_143_rule(Parser *p) return _res; } -// _tmp_144: 'if' disjunction +// _tmp_145: 'if' disjunction static void * -_tmp_144_rule(Parser *p) +_tmp_145_rule(Parser *p) { if (p->error_indicator) { return NULL; @@ -17288,9 +17370,9 @@ _tmp_144_rule(Parser *p) return _res; } -// _tmp_145: ',' star_target +// _tmp_146: ',' star_target static void * -_tmp_145_rule(Parser *p) +_tmp_146_rule(Parser *p) { if (p->error_indicator) { return NULL; @@ -17320,9 +17402,9 @@ _tmp_145_rule(Parser *p) return _res; } -// _loop1_146: param_with_default +// _loop1_147: param_with_default static asdl_seq * -_loop1_146_rule(Parser *p) +_loop1_147_rule(Parser *p) { if (p->error_indicator) { return NULL; @@ -17363,19 +17445,19 @@ _loop1_146_rule(Parser *p) } asdl_seq *_seq = _Py_asdl_seq_new(_n, p->arena); if (!_seq) { - PyErr_Format(PyExc_MemoryError, "asdl_seq_new _loop1_146"); + PyErr_Format(PyExc_MemoryError, "asdl_seq_new _loop1_147"); PyMem_Free(_children); return NULL; } for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop1_146_type, _seq); + _PyPegen_insert_memo(p, _start_mark, _loop1_147_type, _seq); return _seq; } -// _tmp_147: ')' | '**' +// _tmp_148: ')' | '**' static void * -_tmp_147_rule(Parser *p) +_tmp_148_rule(Parser *p) { if (p->error_indicator) { return NULL; @@ -17409,9 +17491,9 @@ _tmp_147_rule(Parser *p) return _res; } -// _tmp_148: ':' | '**' +// _tmp_149: ':' | '**' static void * -_tmp_148_rule(Parser *p) +_tmp_149_rule(Parser *p) { if (p->error_indicator) { return NULL; diff --git a/Parser/pegen/pegen.c b/Parser/pegen/pegen.c index d1e51a9429073a..aa1c5a5fb33972 100644 --- a/Parser/pegen/pegen.c +++ b/Parser/pegen/pegen.c @@ -2068,8 +2068,9 @@ _PyPegen_get_invalid_target(expr_ty e) Py_ssize_t len = asdl_seq_LEN(e->v.List.elts); for (Py_ssize_t i = 0; i < len; i++) { expr_ty other = asdl_seq_GET(e->v.List.elts, i); - if (_PyPegen_get_invalid_target(other)) { - return other; + expr_ty child = _PyPegen_get_invalid_target(other); + if (child != NULL) { + return child; } } return NULL; @@ -2088,6 +2089,8 @@ _PyPegen_get_invalid_target(expr_ty e) case Starred_kind: return _PyPegen_get_invalid_target(e->v.Starred.value); case Name_kind: + case Subscript_kind: + case Attribute_kind: return NULL; default: return e; From b596bbaa83af39fa7b46d3d9c147f15ee2841ba1 Mon Sep 17 00:00:00 2001 From: Pablo Galindo Date: Thu, 14 May 2020 03:20:28 +0100 Subject: [PATCH 3/9] Deduplicate code with macro --- Parser/pegen/pegen.c | 30 ++++++++++++++---------------- 1 file changed, 14 insertions(+), 16 deletions(-) diff --git a/Parser/pegen/pegen.c b/Parser/pegen/pegen.c index aa1c5a5fb33972..e0073cf138ad17 100644 --- a/Parser/pegen/pegen.c +++ b/Parser/pegen/pegen.c @@ -2063,27 +2063,25 @@ _PyPegen_get_invalid_target(expr_ty e) if (e == NULL) { return NULL; } + +#define VISIT_CONTAINER(CONTAINER, TYPE) do { \ + Py_ssize_t len = asdl_seq_LEN(CONTAINER->v.TYPE.elts);\ + for (Py_ssize_t i = 0; i < len; i++) {\ + expr_ty other = asdl_seq_GET(CONTAINER->v.TYPE.elts, i);\ + expr_ty child = _PyPegen_get_invalid_target(other);\ + if (child != NULL) {\ + return child;\ + }\ + }\ + } while (0) + switch (e->kind) { case List_kind: { - Py_ssize_t len = asdl_seq_LEN(e->v.List.elts); - for (Py_ssize_t i = 0; i < len; i++) { - expr_ty other = asdl_seq_GET(e->v.List.elts, i); - expr_ty child = _PyPegen_get_invalid_target(other); - if (child != NULL) { - return child; - } - } + VISIT_CONTAINER(e, List); return NULL; } case Tuple_kind: { - Py_ssize_t len = asdl_seq_LEN(e->v.Tuple.elts); - for (Py_ssize_t i = 0; i < len; i++) { - expr_ty other = asdl_seq_GET(e->v.Tuple.elts, i); - expr_ty child = _PyPegen_get_invalid_target(other); - if (child != NULL) { - return child; - } - } + VISIT_CONTAINER(e, Tuple); return NULL; } case Starred_kind: From 4f2cb72b5ae98e5c24c3b4dfc94b0f121cc70769 Mon Sep 17 00:00:00 2001 From: Pablo Galindo Date: Fri, 15 May 2020 00:38:07 +0100 Subject: [PATCH 4/9] Fix error for augassign --- Grammar/python.gram | 19 ++++++------------- Lib/test/test_syntax.py | 6 +++--- Parser/pegen/parse.c | 2 +- Parser/pegen/pegen.c | 16 +++++++++++++++- Parser/pegen/pegen.h | 2 +- 5 files changed, 26 insertions(+), 19 deletions(-) diff --git a/Grammar/python.gram b/Grammar/python.gram index a2e82f3ef82d75..3dcbba926d7546 100644 --- a/Grammar/python.gram +++ b/Grammar/python.gram @@ -641,20 +641,13 @@ invalid_assignment: | a=expression ':' expression ['=' annotated_rhs] { RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, "illegal target for annotation") } | a=star_expressions '=' (yield_expr | star_expressions) { - RAISE_SYNTAX_ERROR_KNOWN_LOCATION( - _PyPegen_get_invalid_target(a), - "cannot assign to %s", _PyPegen_get_expr_name(_PyPegen_get_invalid_target(a)) - )} - | a=expression augassign (yield_expr | star_expressions) { - RAISE_SYNTAX_ERROR_KNOWN_LOCATION( - _PyPegen_get_invalid_target(a), - "cannot assign to %s", _PyPegen_get_expr_name(_PyPegen_get_invalid_target(a)) - )} + RAISE_SYNTAX_ERROR_KNOWN_LOCATION( + _PyPegen_get_invalid_target(a), + "cannot assign to %s", _PyPegen_get_expr_name(_PyPegen_get_invalid_target(a))) } + | a=expression augassign (yield_expr | star_expressions) { _PyPegen_raise_syntax_error_for_augassign(p, a) } | a=star_expressions augassign (yield_expr | star_expressions) { - RAISE_SYNTAX_ERROR_KNOWN_LOCATION( - a, - "illegal expression for augmented assignment" - )} + RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, "illegal expression for augmented assignment") } + invalid_block: | NEWLINE !INDENT { RAISE_INDENTATION_ERROR("expected an indented block") } invalid_comprehension: diff --git a/Lib/test/test_syntax.py b/Lib/test/test_syntax.py index 258152dabed9cb..b471f88c91f42f 100644 --- a/Lib/test/test_syntax.py +++ b/Lib/test/test_syntax.py @@ -138,15 +138,15 @@ >>> a, b += 1, 2 Traceback (most recent call last): -SyntaxError: invalid syntax +SyntaxError: illegal expression for augmented assignment >>> (a, b) += 1, 2 Traceback (most recent call last): -SyntaxError: cannot assign to tuple +SyntaxError: illegal expression for augmented assignment >>> [a, b] += 1, 2 Traceback (most recent call last): -SyntaxError: cannot assign to list +SyntaxError: illegal expression for augmented assignment From compiler_complex_args(): diff --git a/Parser/pegen/parse.c b/Parser/pegen/parse.c index a068d047d314c7..ddf377a5376608 100644 --- a/Parser/pegen/parse.c +++ b/Parser/pegen/parse.c @@ -10878,7 +10878,7 @@ invalid_assignment_rule(Parser *p) (_tmp_129_var = _tmp_129_rule(p)) // yield_expr | star_expressions ) { - _res = RAISE_SYNTAX_ERROR_KNOWN_LOCATION ( _PyPegen_get_invalid_target ( a ) , "cannot assign to %s" , _PyPegen_get_expr_name ( _PyPegen_get_invalid_target ( a ) ) ); + _res = _PyPegen_raise_syntax_error_for_augassign ( p , a ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; return NULL; diff --git a/Parser/pegen/pegen.c b/Parser/pegen/pegen.c index e0073cf138ad17..e10eae5c2dd01c 100644 --- a/Parser/pegen/pegen.c +++ b/Parser/pegen/pegen.c @@ -2093,4 +2093,18 @@ _PyPegen_get_invalid_target(expr_ty e) default: return e; } -} \ No newline at end of file +} + +void * +_PyPegen_raise_syntax_error_for_augassign(Parser *p, expr_ty e) { + expr_ty invalid_target = _PyPegen_get_invalid_target(e); + + if (invalid_target != NULL) { + RAISE_SYNTAX_ERROR_KNOWN_LOCATION(invalid_target, + "cannot assign to %s", _PyPegen_get_expr_name(invalid_target)); + } else { + RAISE_SYNTAX_ERROR_KNOWN_LOCATION(e, "illegal expression for augmented assignment"); + } + return NULL; +} + diff --git a/Parser/pegen/pegen.h b/Parser/pegen/pegen.h index 964b5599f3d644..4e7f8adc692093 100644 --- a/Parser/pegen/pegen.h +++ b/Parser/pegen/pegen.h @@ -263,7 +263,7 @@ mod_ty _PyPegen_make_module(Parser *, asdl_seq *); // Error reporting helpers expr_ty _PyPegen_get_invalid_target(expr_ty e); - +void *_PyPegen_raise_syntax_error_for_augassign(Parser *p, expr_ty e); void *_PyPegen_parse(Parser *); From c74ecceea9c9673ff0f04d4d92c6b52170e67cf6 Mon Sep 17 00:00:00 2001 From: Pablo Galindo Date: Fri, 15 May 2020 01:02:19 +0100 Subject: [PATCH 5/9] Address Lysandros's feedback --- Grammar/python.gram | 7 +- Lib/test/test_syntax.py | 13 +- Parser/pegen/parse.c | 268 ++++++++++++++++------------------------ Parser/pegen/pegen.c | 16 +-- Parser/pegen/pegen.h | 1 - Python/ast.c | 13 +- 6 files changed, 125 insertions(+), 193 deletions(-) diff --git a/Grammar/python.gram b/Grammar/python.gram index 3dcbba926d7546..9c511fa576303e 100644 --- a/Grammar/python.gram +++ b/Grammar/python.gram @@ -644,9 +644,12 @@ invalid_assignment: RAISE_SYNTAX_ERROR_KNOWN_LOCATION( _PyPegen_get_invalid_target(a), "cannot assign to %s", _PyPegen_get_expr_name(_PyPegen_get_invalid_target(a))) } - | a=expression augassign (yield_expr | star_expressions) { _PyPegen_raise_syntax_error_for_augassign(p, a) } | a=star_expressions augassign (yield_expr | star_expressions) { - RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, "illegal expression for augmented assignment") } + RAISE_SYNTAX_ERROR_KNOWN_LOCATION( + a, + "%s is an illegal expression for augmented assignment", + _PyPegen_get_expr_name(a) + )} invalid_block: | NEWLINE !INDENT { RAISE_INDENTATION_ERROR("expected an indented block") } diff --git a/Lib/test/test_syntax.py b/Lib/test/test_syntax.py index b471f88c91f42f..5ae2c61e9abb6e 100644 --- a/Lib/test/test_syntax.py +++ b/Lib/test/test_syntax.py @@ -138,15 +138,15 @@ >>> a, b += 1, 2 Traceback (most recent call last): -SyntaxError: illegal expression for augmented assignment +SyntaxError: tuple is an illegal expression for augmented assignment >>> (a, b) += 1, 2 Traceback (most recent call last): -SyntaxError: illegal expression for augmented assignment +SyntaxError: tuple is an illegal expression for augmented assignment >>> [a, b] += 1, 2 Traceback (most recent call last): -SyntaxError: illegal expression for augmented assignment +SyntaxError: list is an illegal expression for augmented assignment From compiler_complex_args(): @@ -353,16 +353,16 @@ >>> (x for x in x) += 1 Traceback (most recent call last): -SyntaxError: cannot assign to generator expression +SyntaxError: generator expression is an illegal expression for augmented assignment >>> None += 1 Traceback (most recent call last): -SyntaxError: cannot assign to None +SyntaxError: None is an illegal expression for augmented assignment >>> __debug__ += 1 Traceback (most recent call last): SyntaxError: cannot assign to __debug__ >>> f() += 1 Traceback (most recent call last): -SyntaxError: cannot assign to function call +SyntaxError: function call is an illegal expression for augmented assignment Test continue in finally in weird combinations. @@ -695,6 +695,7 @@ def _check_error(self, code, errtext, def test_assign_call(self): self._check_error("f() = 1", "assign") + @unittest.skipIf(support.use_old_parser(), "The old parser cannot generate these error messages") def test_assign_del(self): self._check_error("del (,)", "invalid syntax") self._check_error("del 1", "delete literal") diff --git a/Parser/pegen/parse.c b/Parser/pegen/parse.c index ddf377a5376608..1bd43410801c9f 100644 --- a/Parser/pegen/parse.c +++ b/Parser/pegen/parse.c @@ -351,8 +351,8 @@ static KeywordToken *reserved_keywords[] = { #define _tmp_128_type 1280 #define _tmp_129_type 1281 #define _tmp_130_type 1282 -#define _tmp_131_type 1283 -#define _loop0_132_type 1284 +#define _loop0_131_type 1283 +#define _tmp_132_type 1284 #define _tmp_133_type 1285 #define _tmp_134_type 1286 #define _tmp_135_type 1287 @@ -366,10 +366,9 @@ static KeywordToken *reserved_keywords[] = { #define _tmp_143_type 1295 #define _tmp_144_type 1296 #define _tmp_145_type 1297 -#define _tmp_146_type 1298 -#define _loop1_147_type 1299 +#define _loop1_146_type 1298 +#define _tmp_147_type 1299 #define _tmp_148_type 1300 -#define _tmp_149_type 1301 static mod_ty file_rule(Parser *p); static mod_ty interactive_rule(Parser *p); @@ -654,8 +653,8 @@ static void *_tmp_127_rule(Parser *p); static void *_tmp_128_rule(Parser *p); static void *_tmp_129_rule(Parser *p); static void *_tmp_130_rule(Parser *p); -static void *_tmp_131_rule(Parser *p); -static asdl_seq *_loop0_132_rule(Parser *p); +static asdl_seq *_loop0_131_rule(Parser *p); +static void *_tmp_132_rule(Parser *p); static void *_tmp_133_rule(Parser *p); static void *_tmp_134_rule(Parser *p); static void *_tmp_135_rule(Parser *p); @@ -669,10 +668,9 @@ static void *_tmp_142_rule(Parser *p); static void *_tmp_143_rule(Parser *p); static void *_tmp_144_rule(Parser *p); static void *_tmp_145_rule(Parser *p); -static void *_tmp_146_rule(Parser *p); -static asdl_seq *_loop1_147_rule(Parser *p); +static asdl_seq *_loop1_146_rule(Parser *p); +static void *_tmp_147_rule(Parser *p); static void *_tmp_148_rule(Parser *p); -static void *_tmp_149_rule(Parser *p); // file: statements? $ @@ -10750,7 +10748,6 @@ invalid_named_expression_rule(Parser *p) // | star_named_expression ',' star_named_expressions* ':' // | expression ':' expression ['=' annotated_rhs] // | star_expressions '=' (yield_expr | star_expressions) -// | expression augassign (yield_expr | star_expressions) // | star_expressions augassign (yield_expr | star_expressions) static void * invalid_assignment_rule(Parser *p) @@ -10866,29 +10863,8 @@ invalid_assignment_rule(Parser *p) } p->mark = _mark; } - { // expression augassign (yield_expr | star_expressions) - void *_tmp_129_var; - expr_ty a; - AugOperator* augassign_var; - if ( - (a = expression_rule(p)) // expression - && - (augassign_var = augassign_rule(p)) // augassign - && - (_tmp_129_var = _tmp_129_rule(p)) // yield_expr | star_expressions - ) - { - _res = _PyPegen_raise_syntax_error_for_augassign ( p , a ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - return NULL; - } - goto done; - } - p->mark = _mark; - } { // star_expressions augassign (yield_expr | star_expressions) - void *_tmp_130_var; + void *_tmp_129_var; expr_ty a; AugOperator* augassign_var; if ( @@ -10896,10 +10872,10 @@ invalid_assignment_rule(Parser *p) && (augassign_var = augassign_rule(p)) // augassign && - (_tmp_130_var = _tmp_130_rule(p)) // yield_expr | star_expressions + (_tmp_129_var = _tmp_129_rule(p)) // yield_expr | star_expressions ) { - _res = RAISE_SYNTAX_ERROR_KNOWN_LOCATION ( a , "illegal expression for augmented assignment" ); + _res = RAISE_SYNTAX_ERROR_KNOWN_LOCATION ( a , "%s is an illegal expression for augmented assignment" , _PyPegen_get_expr_name ( a ) ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; return NULL; @@ -10954,11 +10930,11 @@ invalid_comprehension_rule(Parser *p) void * _res = NULL; int _mark = p->mark; { // ('[' | '(' | '{') starred_expression for_if_clauses - void *_tmp_131_var; + void *_tmp_130_var; expr_ty a; asdl_seq* for_if_clauses_var; if ( - (_tmp_131_var = _tmp_131_rule(p)) // '[' | '(' | '{' + (_tmp_130_var = _tmp_130_rule(p)) // '[' | '(' | '{' && (a = starred_expression_rule(p)) // starred_expression && @@ -10990,13 +10966,13 @@ invalid_parameters_rule(Parser *p) void * _res = NULL; int _mark = p->mark; { // param_no_default* (slash_with_default | param_with_default+) param_no_default - asdl_seq * _loop0_132_var; - void *_tmp_133_var; + asdl_seq * _loop0_131_var; + void *_tmp_132_var; arg_ty param_no_default_var; if ( - (_loop0_132_var = _loop0_132_rule(p)) // param_no_default* + (_loop0_131_var = _loop0_131_rule(p)) // param_no_default* && - (_tmp_133_var = _tmp_133_rule(p)) // slash_with_default | param_with_default+ + (_tmp_132_var = _tmp_132_rule(p)) // slash_with_default | param_with_default+ && (param_no_default_var = param_no_default_rule(p)) // param_no_default ) @@ -11026,11 +11002,11 @@ invalid_star_etc_rule(Parser *p) int _mark = p->mark; { // '*' (')' | ',' (')' | '**')) Token * _literal; - void *_tmp_134_var; + void *_tmp_133_var; if ( (_literal = _PyPegen_expect_token(p, 16)) // token='*' && - (_tmp_134_var = _tmp_134_rule(p)) // ')' | ',' (')' | '**') + (_tmp_133_var = _tmp_133_rule(p)) // ')' | ',' (')' | '**') ) { _res = RAISE_SYNTAX_ERROR ( "named arguments must follow bare *" ); @@ -11058,11 +11034,11 @@ invalid_lambda_star_etc_rule(Parser *p) int _mark = p->mark; { // '*' (':' | ',' (':' | '**')) Token * _literal; - void *_tmp_135_var; + void *_tmp_134_var; if ( (_literal = _PyPegen_expect_token(p, 16)) // token='*' && - (_tmp_135_var = _tmp_135_rule(p)) // ':' | ',' (':' | '**') + (_tmp_134_var = _tmp_134_rule(p)) // ':' | ',' (':' | '**') ) { _res = RAISE_SYNTAX_ERROR ( "named arguments must follow bare *" ); @@ -12046,12 +12022,12 @@ _loop1_22_rule(Parser *p) ssize_t _children_capacity = 1; ssize_t _n = 0; { // (star_targets '=') - void *_tmp_136_var; + void *_tmp_135_var; while ( - (_tmp_136_var = _tmp_136_rule(p)) // star_targets '=' + (_tmp_135_var = _tmp_135_rule(p)) // star_targets '=' ) { - _res = _tmp_136_var; + _res = _tmp_135_var; if (_n == _children_capacity) { _children_capacity *= 2; _children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); @@ -12373,12 +12349,12 @@ _loop0_30_rule(Parser *p) ssize_t _children_capacity = 1; ssize_t _n = 0; { // ('.' | '...') - void *_tmp_137_var; + void *_tmp_136_var; while ( - (_tmp_137_var = _tmp_137_rule(p)) // '.' | '...' + (_tmp_136_var = _tmp_136_rule(p)) // '.' | '...' ) { - _res = _tmp_137_var; + _res = _tmp_136_var; if (_n == _children_capacity) { _children_capacity *= 2; _children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); @@ -12422,12 +12398,12 @@ _loop1_31_rule(Parser *p) ssize_t _children_capacity = 1; ssize_t _n = 0; { // ('.' | '...') - void *_tmp_138_var; + void *_tmp_137_var; while ( - (_tmp_138_var = _tmp_138_rule(p)) // '.' | '...' + (_tmp_137_var = _tmp_137_rule(p)) // '.' | '...' ) { - _res = _tmp_138_var; + _res = _tmp_137_var; if (_n == _children_capacity) { _children_capacity *= 2; _children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); @@ -14004,12 +13980,12 @@ _loop1_67_rule(Parser *p) ssize_t _children_capacity = 1; ssize_t _n = 0; { // ('@' named_expression NEWLINE) - void *_tmp_139_var; + void *_tmp_138_var; while ( - (_tmp_139_var = _tmp_139_rule(p)) // '@' named_expression NEWLINE + (_tmp_138_var = _tmp_138_rule(p)) // '@' named_expression NEWLINE ) { - _res = _tmp_139_var; + _res = _tmp_138_var; if (_n == _children_capacity) { _children_capacity *= 2; _children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); @@ -14177,12 +14153,12 @@ _loop1_71_rule(Parser *p) ssize_t _children_capacity = 1; ssize_t _n = 0; { // (',' star_expression) - void *_tmp_140_var; + void *_tmp_139_var; while ( - (_tmp_140_var = _tmp_140_rule(p)) // ',' star_expression + (_tmp_139_var = _tmp_139_rule(p)) // ',' star_expression ) { - _res = _tmp_140_var; + _res = _tmp_139_var; if (_n == _children_capacity) { _children_capacity *= 2; _children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); @@ -14315,12 +14291,12 @@ _loop1_74_rule(Parser *p) ssize_t _children_capacity = 1; ssize_t _n = 0; { // (',' expression) - void *_tmp_141_var; + void *_tmp_140_var; while ( - (_tmp_141_var = _tmp_141_rule(p)) // ',' expression + (_tmp_140_var = _tmp_140_rule(p)) // ',' expression ) { - _res = _tmp_141_var; + _res = _tmp_140_var; if (_n == _children_capacity) { _children_capacity *= 2; _children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); @@ -15082,12 +15058,12 @@ _loop1_89_rule(Parser *p) ssize_t _children_capacity = 1; ssize_t _n = 0; { // ('or' conjunction) - void *_tmp_142_var; + void *_tmp_141_var; while ( - (_tmp_142_var = _tmp_142_rule(p)) // 'or' conjunction + (_tmp_141_var = _tmp_141_rule(p)) // 'or' conjunction ) { - _res = _tmp_142_var; + _res = _tmp_141_var; if (_n == _children_capacity) { _children_capacity *= 2; _children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); @@ -15135,12 +15111,12 @@ _loop1_90_rule(Parser *p) ssize_t _children_capacity = 1; ssize_t _n = 0; { // ('and' inversion) - void *_tmp_143_var; + void *_tmp_142_var; while ( - (_tmp_143_var = _tmp_143_rule(p)) // 'and' inversion + (_tmp_142_var = _tmp_142_rule(p)) // 'and' inversion ) { - _res = _tmp_143_var; + _res = _tmp_142_var; if (_n == _children_capacity) { _children_capacity *= 2; _children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); @@ -15790,12 +15766,12 @@ _loop0_105_rule(Parser *p) ssize_t _children_capacity = 1; ssize_t _n = 0; { // ('if' disjunction) - void *_tmp_144_var; + void *_tmp_143_var; while ( - (_tmp_144_var = _tmp_144_rule(p)) // 'if' disjunction + (_tmp_143_var = _tmp_143_rule(p)) // 'if' disjunction ) { - _res = _tmp_144_var; + _res = _tmp_143_var; if (_n == _children_capacity) { _children_capacity *= 2; _children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); @@ -15839,12 +15815,12 @@ _loop0_106_rule(Parser *p) ssize_t _children_capacity = 1; ssize_t _n = 0; { // ('if' disjunction) - void *_tmp_145_var; + void *_tmp_144_var; while ( - (_tmp_145_var = _tmp_145_rule(p)) // 'if' disjunction + (_tmp_144_var = _tmp_144_rule(p)) // 'if' disjunction ) { - _res = _tmp_145_var; + _res = _tmp_144_var; if (_n == _children_capacity) { _children_capacity *= 2; _children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); @@ -16292,12 +16268,12 @@ _loop0_117_rule(Parser *p) ssize_t _children_capacity = 1; ssize_t _n = 0; { // (',' star_target) - void *_tmp_146_var; + void *_tmp_145_var; while ( - (_tmp_146_var = _tmp_146_rule(p)) // ',' star_target + (_tmp_145_var = _tmp_145_rule(p)) // ',' star_target ) { - _res = _tmp_146_var; + _res = _tmp_145_var; if (_n == _children_capacity) { _children_capacity *= 2; _children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); @@ -16793,45 +16769,9 @@ _tmp_129_rule(Parser *p) return _res; } -// _tmp_130: yield_expr | star_expressions +// _tmp_130: '[' | '(' | '{' static void * _tmp_130_rule(Parser *p) -{ - if (p->error_indicator) { - return NULL; - } - void * _res = NULL; - int _mark = p->mark; - { // yield_expr - expr_ty yield_expr_var; - if ( - (yield_expr_var = yield_expr_rule(p)) // yield_expr - ) - { - _res = yield_expr_var; - goto done; - } - p->mark = _mark; - } - { // star_expressions - expr_ty star_expressions_var; - if ( - (star_expressions_var = star_expressions_rule(p)) // star_expressions - ) - { - _res = star_expressions_var; - goto done; - } - p->mark = _mark; - } - _res = NULL; - done: - return _res; -} - -// _tmp_131: '[' | '(' | '{' -static void * -_tmp_131_rule(Parser *p) { if (p->error_indicator) { return NULL; @@ -16876,9 +16816,9 @@ _tmp_131_rule(Parser *p) return _res; } -// _loop0_132: param_no_default +// _loop0_131: param_no_default static asdl_seq * -_loop0_132_rule(Parser *p) +_loop0_131_rule(Parser *p) { if (p->error_indicator) { return NULL; @@ -16915,19 +16855,19 @@ _loop0_132_rule(Parser *p) } asdl_seq *_seq = _Py_asdl_seq_new(_n, p->arena); if (!_seq) { - PyErr_Format(PyExc_MemoryError, "asdl_seq_new _loop0_132"); + PyErr_Format(PyExc_MemoryError, "asdl_seq_new _loop0_131"); PyMem_Free(_children); return NULL; } for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_132_type, _seq); + _PyPegen_insert_memo(p, _start_mark, _loop0_131_type, _seq); return _seq; } -// _tmp_133: slash_with_default | param_with_default+ +// _tmp_132: slash_with_default | param_with_default+ static void * -_tmp_133_rule(Parser *p) +_tmp_132_rule(Parser *p) { if (p->error_indicator) { return NULL; @@ -16946,12 +16886,12 @@ _tmp_133_rule(Parser *p) p->mark = _mark; } { // param_with_default+ - asdl_seq * _loop1_147_var; + asdl_seq * _loop1_146_var; if ( - (_loop1_147_var = _loop1_147_rule(p)) // param_with_default+ + (_loop1_146_var = _loop1_146_rule(p)) // param_with_default+ ) { - _res = _loop1_147_var; + _res = _loop1_146_var; goto done; } p->mark = _mark; @@ -16961,9 +16901,9 @@ _tmp_133_rule(Parser *p) return _res; } -// _tmp_134: ')' | ',' (')' | '**') +// _tmp_133: ')' | ',' (')' | '**') static void * -_tmp_134_rule(Parser *p) +_tmp_133_rule(Parser *p) { if (p->error_indicator) { return NULL; @@ -16983,14 +16923,14 @@ _tmp_134_rule(Parser *p) } { // ',' (')' | '**') Token * _literal; - void *_tmp_148_var; + void *_tmp_147_var; if ( (_literal = _PyPegen_expect_token(p, 12)) // token=',' && - (_tmp_148_var = _tmp_148_rule(p)) // ')' | '**' + (_tmp_147_var = _tmp_147_rule(p)) // ')' | '**' ) { - _res = _PyPegen_dummy_name(p, _literal, _tmp_148_var); + _res = _PyPegen_dummy_name(p, _literal, _tmp_147_var); goto done; } p->mark = _mark; @@ -17000,9 +16940,9 @@ _tmp_134_rule(Parser *p) return _res; } -// _tmp_135: ':' | ',' (':' | '**') +// _tmp_134: ':' | ',' (':' | '**') static void * -_tmp_135_rule(Parser *p) +_tmp_134_rule(Parser *p) { if (p->error_indicator) { return NULL; @@ -17022,14 +16962,14 @@ _tmp_135_rule(Parser *p) } { // ',' (':' | '**') Token * _literal; - void *_tmp_149_var; + void *_tmp_148_var; if ( (_literal = _PyPegen_expect_token(p, 12)) // token=',' && - (_tmp_149_var = _tmp_149_rule(p)) // ':' | '**' + (_tmp_148_var = _tmp_148_rule(p)) // ':' | '**' ) { - _res = _PyPegen_dummy_name(p, _literal, _tmp_149_var); + _res = _PyPegen_dummy_name(p, _literal, _tmp_148_var); goto done; } p->mark = _mark; @@ -17039,9 +16979,9 @@ _tmp_135_rule(Parser *p) return _res; } -// _tmp_136: star_targets '=' +// _tmp_135: star_targets '=' static void * -_tmp_136_rule(Parser *p) +_tmp_135_rule(Parser *p) { if (p->error_indicator) { return NULL; @@ -17071,9 +17011,9 @@ _tmp_136_rule(Parser *p) return _res; } -// _tmp_137: '.' | '...' +// _tmp_136: '.' | '...' static void * -_tmp_137_rule(Parser *p) +_tmp_136_rule(Parser *p) { if (p->error_indicator) { return NULL; @@ -17107,9 +17047,9 @@ _tmp_137_rule(Parser *p) return _res; } -// _tmp_138: '.' | '...' +// _tmp_137: '.' | '...' static void * -_tmp_138_rule(Parser *p) +_tmp_137_rule(Parser *p) { if (p->error_indicator) { return NULL; @@ -17143,9 +17083,9 @@ _tmp_138_rule(Parser *p) return _res; } -// _tmp_139: '@' named_expression NEWLINE +// _tmp_138: '@' named_expression NEWLINE static void * -_tmp_139_rule(Parser *p) +_tmp_138_rule(Parser *p) { if (p->error_indicator) { return NULL; @@ -17178,9 +17118,9 @@ _tmp_139_rule(Parser *p) return _res; } -// _tmp_140: ',' star_expression +// _tmp_139: ',' star_expression static void * -_tmp_140_rule(Parser *p) +_tmp_139_rule(Parser *p) { if (p->error_indicator) { return NULL; @@ -17210,9 +17150,9 @@ _tmp_140_rule(Parser *p) return _res; } -// _tmp_141: ',' expression +// _tmp_140: ',' expression static void * -_tmp_141_rule(Parser *p) +_tmp_140_rule(Parser *p) { if (p->error_indicator) { return NULL; @@ -17242,9 +17182,9 @@ _tmp_141_rule(Parser *p) return _res; } -// _tmp_142: 'or' conjunction +// _tmp_141: 'or' conjunction static void * -_tmp_142_rule(Parser *p) +_tmp_141_rule(Parser *p) { if (p->error_indicator) { return NULL; @@ -17274,9 +17214,9 @@ _tmp_142_rule(Parser *p) return _res; } -// _tmp_143: 'and' inversion +// _tmp_142: 'and' inversion static void * -_tmp_143_rule(Parser *p) +_tmp_142_rule(Parser *p) { if (p->error_indicator) { return NULL; @@ -17306,9 +17246,9 @@ _tmp_143_rule(Parser *p) return _res; } -// _tmp_144: 'if' disjunction +// _tmp_143: 'if' disjunction static void * -_tmp_144_rule(Parser *p) +_tmp_143_rule(Parser *p) { if (p->error_indicator) { return NULL; @@ -17338,9 +17278,9 @@ _tmp_144_rule(Parser *p) return _res; } -// _tmp_145: 'if' disjunction +// _tmp_144: 'if' disjunction static void * -_tmp_145_rule(Parser *p) +_tmp_144_rule(Parser *p) { if (p->error_indicator) { return NULL; @@ -17370,9 +17310,9 @@ _tmp_145_rule(Parser *p) return _res; } -// _tmp_146: ',' star_target +// _tmp_145: ',' star_target static void * -_tmp_146_rule(Parser *p) +_tmp_145_rule(Parser *p) { if (p->error_indicator) { return NULL; @@ -17402,9 +17342,9 @@ _tmp_146_rule(Parser *p) return _res; } -// _loop1_147: param_with_default +// _loop1_146: param_with_default static asdl_seq * -_loop1_147_rule(Parser *p) +_loop1_146_rule(Parser *p) { if (p->error_indicator) { return NULL; @@ -17445,19 +17385,19 @@ _loop1_147_rule(Parser *p) } asdl_seq *_seq = _Py_asdl_seq_new(_n, p->arena); if (!_seq) { - PyErr_Format(PyExc_MemoryError, "asdl_seq_new _loop1_147"); + PyErr_Format(PyExc_MemoryError, "asdl_seq_new _loop1_146"); PyMem_Free(_children); return NULL; } for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop1_147_type, _seq); + _PyPegen_insert_memo(p, _start_mark, _loop1_146_type, _seq); return _seq; } -// _tmp_148: ')' | '**' +// _tmp_147: ')' | '**' static void * -_tmp_148_rule(Parser *p) +_tmp_147_rule(Parser *p) { if (p->error_indicator) { return NULL; @@ -17491,9 +17431,9 @@ _tmp_148_rule(Parser *p) return _res; } -// _tmp_149: ':' | '**' +// _tmp_148: ':' | '**' static void * -_tmp_149_rule(Parser *p) +_tmp_148_rule(Parser *p) { if (p->error_indicator) { return NULL; diff --git a/Parser/pegen/pegen.c b/Parser/pegen/pegen.c index e10eae5c2dd01c..e0073cf138ad17 100644 --- a/Parser/pegen/pegen.c +++ b/Parser/pegen/pegen.c @@ -2093,18 +2093,4 @@ _PyPegen_get_invalid_target(expr_ty e) default: return e; } -} - -void * -_PyPegen_raise_syntax_error_for_augassign(Parser *p, expr_ty e) { - expr_ty invalid_target = _PyPegen_get_invalid_target(e); - - if (invalid_target != NULL) { - RAISE_SYNTAX_ERROR_KNOWN_LOCATION(invalid_target, - "cannot assign to %s", _PyPegen_get_expr_name(invalid_target)); - } else { - RAISE_SYNTAX_ERROR_KNOWN_LOCATION(e, "illegal expression for augmented assignment"); - } - return NULL; -} - +} \ No newline at end of file diff --git a/Parser/pegen/pegen.h b/Parser/pegen/pegen.h index 4e7f8adc692093..b9d4c048bb52b0 100644 --- a/Parser/pegen/pegen.h +++ b/Parser/pegen/pegen.h @@ -263,7 +263,6 @@ mod_ty _PyPegen_make_module(Parser *, asdl_seq *); // Error reporting helpers expr_ty _PyPegen_get_invalid_target(expr_ty e); -void *_PyPegen_raise_syntax_error_for_augassign(Parser *p, expr_ty e); void *_PyPegen_parse(Parser *); diff --git a/Python/ast.c b/Python/ast.c index 1a4a3110e69559..cef464039c2f7a 100644 --- a/Python/ast.c +++ b/Python/ast.c @@ -3164,10 +3164,7 @@ ast_for_expr_stmt(struct compiling *c, const node *n) expr1 = ast_for_testlist(c, ch); if (!expr1) return NULL; - if(!set_context(c, expr1, Store, ch)) - return NULL; - /* set_context checks that most expressions are not the left side. - Augmented assignments can only have a name, a subscript, or an + /* Augmented assignments can only have a name, a subscript, or an attribute on the left, though, so we have to explicitly check for those. */ switch (expr1->kind) { @@ -3176,10 +3173,16 @@ ast_for_expr_stmt(struct compiling *c, const node *n) case Subscript_kind: break; default: - ast_error(c, ch, "illegal expression for augmented assignment"); + ast_error(c, ch, "%s is an illegal expression for augmented assignment", + get_expr_name(expr1)); return NULL; } + /* set_context checks that most expressions are not the left side. */ + if(!set_context(c, expr1, Store, ch)) { + return NULL; + } + ch = CHILD(n, 2); if (TYPE(ch) == testlist) expr2 = ast_for_testlist(c, ch); From 6d1d63cfe9cb6067cbd00546d27537b0f7e85506 Mon Sep 17 00:00:00 2001 From: Pablo Galindo Date: Fri, 15 May 2020 01:13:23 +0100 Subject: [PATCH 6/9] Add quotes around the node type --- Grammar/python.gram | 2 +- Lib/test/test_syntax.py | 12 ++++++------ Parser/pegen/parse.c | 2 +- Python/ast.c | 2 +- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/Grammar/python.gram b/Grammar/python.gram index 9c511fa576303e..cca92090546265 100644 --- a/Grammar/python.gram +++ b/Grammar/python.gram @@ -647,7 +647,7 @@ invalid_assignment: | a=star_expressions augassign (yield_expr | star_expressions) { RAISE_SYNTAX_ERROR_KNOWN_LOCATION( a, - "%s is an illegal expression for augmented assignment", + "'%s' is an illegal expression for augmented assignment", _PyPegen_get_expr_name(a) )} diff --git a/Lib/test/test_syntax.py b/Lib/test/test_syntax.py index 5ae2c61e9abb6e..60c7d9fd3868e8 100644 --- a/Lib/test/test_syntax.py +++ b/Lib/test/test_syntax.py @@ -138,15 +138,15 @@ >>> a, b += 1, 2 Traceback (most recent call last): -SyntaxError: tuple is an illegal expression for augmented assignment +SyntaxError: 'tuple' is an illegal expression for augmented assignment >>> (a, b) += 1, 2 Traceback (most recent call last): -SyntaxError: tuple is an illegal expression for augmented assignment +SyntaxError: 'tuple' is an illegal expression for augmented assignment >>> [a, b] += 1, 2 Traceback (most recent call last): -SyntaxError: list is an illegal expression for augmented assignment +SyntaxError: 'list' is an illegal expression for augmented assignment From compiler_complex_args(): @@ -353,16 +353,16 @@ >>> (x for x in x) += 1 Traceback (most recent call last): -SyntaxError: generator expression is an illegal expression for augmented assignment +SyntaxError: 'generator expression' is an illegal expression for augmented assignment >>> None += 1 Traceback (most recent call last): -SyntaxError: None is an illegal expression for augmented assignment +SyntaxError: 'None' is an illegal expression for augmented assignment >>> __debug__ += 1 Traceback (most recent call last): SyntaxError: cannot assign to __debug__ >>> f() += 1 Traceback (most recent call last): -SyntaxError: function call is an illegal expression for augmented assignment +SyntaxError: 'function call' is an illegal expression for augmented assignment Test continue in finally in weird combinations. diff --git a/Parser/pegen/parse.c b/Parser/pegen/parse.c index 1bd43410801c9f..f4c5692212768d 100644 --- a/Parser/pegen/parse.c +++ b/Parser/pegen/parse.c @@ -10875,7 +10875,7 @@ invalid_assignment_rule(Parser *p) (_tmp_129_var = _tmp_129_rule(p)) // yield_expr | star_expressions ) { - _res = RAISE_SYNTAX_ERROR_KNOWN_LOCATION ( a , "%s is an illegal expression for augmented assignment" , _PyPegen_get_expr_name ( a ) ); + _res = RAISE_SYNTAX_ERROR_KNOWN_LOCATION ( a , "'%s' is an illegal expression for augmented assignment" , _PyPegen_get_expr_name ( a ) ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; return NULL; diff --git a/Python/ast.c b/Python/ast.c index cef464039c2f7a..2d20ca62aa8378 100644 --- a/Python/ast.c +++ b/Python/ast.c @@ -3173,7 +3173,7 @@ ast_for_expr_stmt(struct compiling *c, const node *n) case Subscript_kind: break; default: - ast_error(c, ch, "%s is an illegal expression for augmented assignment", + ast_error(c, ch, "'%s' is an illegal expression for augmented assignment", get_expr_name(expr1)); return NULL; } From 00a2205b87f8a43358407212241a4fc0f6e82af3 Mon Sep 17 00:00:00 2001 From: Pablo Galindo Date: Fri, 15 May 2020 01:26:29 +0100 Subject: [PATCH 7/9] Update test_dictcomps, test_genexps and test_generators --- Lib/test/test_dictcomps.py | 2 +- Lib/test/test_generators.py | 2 +- Lib/test/test_genexps.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Lib/test/test_dictcomps.py b/Lib/test/test_dictcomps.py index 16aa651b93c46b..472e3dfa0d8a0a 100644 --- a/Lib/test/test_dictcomps.py +++ b/Lib/test/test_dictcomps.py @@ -77,7 +77,7 @@ def test_illegal_assignment(self): compile("{x: y for y, x in ((1, 2), (3, 4))} = 5", "", "exec") - with self.assertRaisesRegex(SyntaxError, "cannot assign"): + with self.assertRaisesRegex(SyntaxError, "illegal expression"): compile("{x: y for y, x in ((1, 2), (3, 4))} += 5", "", "exec") diff --git a/Lib/test/test_generators.py b/Lib/test/test_generators.py index 1081107ee64ace..13070c39b75c00 100644 --- a/Lib/test/test_generators.py +++ b/Lib/test/test_generators.py @@ -1921,7 +1921,7 @@ def printsolution(self, x): >>> def f(): (yield bar) += y Traceback (most recent call last): ... -SyntaxError: cannot assign to yield expression +SyntaxError: yield expression is an illegal expression for augmented assignment Now check some throw() conditions: diff --git a/Lib/test/test_genexps.py b/Lib/test/test_genexps.py index 86e4e195f55ec5..ea41a63ff5f7f1 100644 --- a/Lib/test/test_genexps.py +++ b/Lib/test/test_genexps.py @@ -158,7 +158,7 @@ >>> (y for y in (1,2)) += 10 Traceback (most recent call last): ... - SyntaxError: cannot assign to generator expression + SyntaxError: generator expression is an illegal expression for augmented assignment ########### Tests borrowed from or inspired by test_generators.py ############ From 349ea59b84f34d5ad3af3c23cfe4876e8d4d6443 Mon Sep 17 00:00:00 2001 From: Pablo Galindo Date: Fri, 15 May 2020 01:32:47 +0100 Subject: [PATCH 8/9] Update some tests to the new errors --- Lib/test/test_generators.py | 2 +- Lib/test/test_genexps.py | 2 +- Lib/test/test_peg_parser.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Lib/test/test_generators.py b/Lib/test/test_generators.py index 13070c39b75c00..348ae15aa6532b 100644 --- a/Lib/test/test_generators.py +++ b/Lib/test/test_generators.py @@ -1921,7 +1921,7 @@ def printsolution(self, x): >>> def f(): (yield bar) += y Traceback (most recent call last): ... -SyntaxError: yield expression is an illegal expression for augmented assignment +SyntaxError: 'yield expression' is an illegal expression for augmented assignment Now check some throw() conditions: diff --git a/Lib/test/test_genexps.py b/Lib/test/test_genexps.py index ea41a63ff5f7f1..5c1a209b0e9908 100644 --- a/Lib/test/test_genexps.py +++ b/Lib/test/test_genexps.py @@ -158,7 +158,7 @@ >>> (y for y in (1,2)) += 10 Traceback (most recent call last): ... - SyntaxError: generator expression is an illegal expression for augmented assignment + SyntaxError: 'generator expression' is an illegal expression for augmented assignment ########### Tests borrowed from or inspired by test_generators.py ############ diff --git a/Lib/test/test_peg_parser.py b/Lib/test/test_peg_parser.py index 71e071940de2f4..9614e45799dd8c 100644 --- a/Lib/test/test_peg_parser.py +++ b/Lib/test/test_peg_parser.py @@ -625,7 +625,7 @@ def f(): ("(a, b): int", "only single target (not tuple) can be annotated"), ("[a, b]: int", "only single target (not list) can be annotated"), ("a(): int", "illegal target for annotation"), - ("1 += 1", "cannot assign to literal"), + ("1 += 1", "'literal' is an illegal expression for augmented assignment"), ("pass\n pass", "unexpected indent"), ("def f():\npass", "expected an indented block"), ("def f(*): pass", "named arguments must follow bare *"), From 6a5c4edb3c34d9debf7d93a368443347c8d3ec7c Mon Sep 17 00:00:00 2001 From: Pablo Galindo Date: Fri, 15 May 2020 01:42:18 +0100 Subject: [PATCH 9/9] Add a comment explaining why we only visit Tuples and Lists --- Parser/pegen/pegen.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Parser/pegen/pegen.c b/Parser/pegen/pegen.c index e0073cf138ad17..7f3e4561de6055 100644 --- a/Parser/pegen/pegen.c +++ b/Parser/pegen/pegen.c @@ -2075,6 +2075,12 @@ _PyPegen_get_invalid_target(expr_ty e) }\ } while (0) + // We only need to visit List and Tuple nodes recursively as those + // are the only ones that can contain valid names in targets when + // they are parsed as expressions. Any other kind of expression + // that is a container (like Sets or Dicts) is directly invalid and + // we don't need to visit it recursively. + switch (e->kind) { case List_kind: { VISIT_CONTAINER(e, List); pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy