From 490a79e970cae91d1383a9081186b0b809be6da5 Mon Sep 17 00:00:00 2001 From: hauntsaninja <> Date: Thu, 14 May 2020 00:26:47 -0700 Subject: [PATCH 1/2] test_syntax: add try-except cases that crash with the new parser --- Lib/test/test_syntax.py | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/Lib/test/test_syntax.py b/Lib/test/test_syntax.py index 06636ae8a149a4..75d754152852e5 100644 --- a/Lib/test/test_syntax.py +++ b/Lib/test/test_syntax.py @@ -529,6 +529,31 @@ ... SyntaxError: no binding for nonlocal '_A__x' found +Tests for try-except clauses: + >>> try: + ... ... + ... except Exception as a.b: + ... pass + Traceback (most recent call last): + ... + SyntaxError: invalid syntax + + >>> try: + ... ... + ... except Exception as a[0]: + ... pass + Traceback (most recent call last): + ... + SyntaxError: invalid syntax + + >>> try: + ... ... + ... except Exception as (a): + ... pass + Traceback (most recent call last): + ... + SyntaxError: invalid syntax + This tests assignment-context; there was a bug in Python 2.5 where compiling a complex 'if' (one with 'elif') would fail to notice an invalid suite, From ff13ce07199b8f879dad69bd81c59c0bfc2f28f6 Mon Sep 17 00:00:00 2001 From: hauntsaninja <> Date: Thu, 14 May 2020 00:28:03 -0700 Subject: [PATCH 2/2] pegen: make except take a NAME, not a target --- Grammar/python.gram | 2 +- Parser/pegen/parse.c | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Grammar/python.gram b/Grammar/python.gram index 84c89330e3ee9d..4c4201c6442714 100644 --- a/Grammar/python.gram +++ b/Grammar/python.gram @@ -185,7 +185,7 @@ try_stmt[stmt_ty]: | 'try' ':' b=block f=finally_block { _Py_Try(b, NULL, NULL, f, EXTRA) } | 'try' ':' b=block ex=except_block+ el=[else_block] f=[finally_block] { _Py_Try(b, ex, el, f, EXTRA) } except_block[excepthandler_ty]: - | 'except' e=expression t=['as' z=target { z }] ':' b=block { + | 'except' e=expression t=['as' z=NAME { z }] ':' b=block { _Py_ExceptHandler(e, (t) ? ((expr_ty) t)->v.Name.id : NULL, b, EXTRA) } | 'except' ':' b=block { _Py_ExceptHandler(NULL, NULL, b, EXTRA) } finally_block[asdl_seq*]: 'finally' ':' a=block { a } diff --git a/Parser/pegen/parse.c b/Parser/pegen/parse.c index b1b248187ea3ed..f1a0e96b1a5d43 100644 --- a/Parser/pegen/parse.c +++ b/Parser/pegen/parse.c @@ -3350,7 +3350,7 @@ try_stmt_rule(Parser *p) return _res; } -// except_block: 'except' expression ['as' target] ':' block | 'except' ':' block +// except_block: 'except' expression ['as' NAME] ':' block | 'except' ':' block static excepthandler_ty except_block_rule(Parser *p) { @@ -3367,7 +3367,7 @@ except_block_rule(Parser *p) UNUSED(_start_lineno); // Only used by EXTRA macro int _start_col_offset = p->tokens[_mark]->col_offset; UNUSED(_start_col_offset); // Only used by EXTRA macro - { // 'except' expression ['as' target] ':' block + { // 'except' expression ['as' NAME] ':' block Token * _keyword; Token * _literal; asdl_seq* b; @@ -3378,7 +3378,7 @@ except_block_rule(Parser *p) && (e = expression_rule(p)) // expression && - (t = _tmp_48_rule(p), 1) // ['as' target] + (t = _tmp_48_rule(p), 1) // ['as' NAME] && (_literal = _PyPegen_expect_token(p, 11)) // token=':' && @@ -13073,7 +13073,7 @@ _loop1_47_rule(Parser *p) return _seq; } -// _tmp_48: 'as' target +// _tmp_48: 'as' NAME static void * _tmp_48_rule(Parser *p) { @@ -13082,13 +13082,13 @@ _tmp_48_rule(Parser *p) } void * _res = NULL; int _mark = p->mark; - { // 'as' target + { // 'as' NAME Token * _keyword; expr_ty z; if ( (_keyword = _PyPegen_expect_token(p, 531)) // token='as' && - (z = target_rule(p)) // target + (z = _PyPegen_name_token(p)) // NAME ) { _res = z;