From 27e4ca9ff68d8e4cec5328604c05b5e2b041a460 Mon Sep 17 00:00:00 2001 From: Irit Katriel Date: Sun, 6 Nov 2022 13:19:34 +0000 Subject: [PATCH 1/4] gh-99153: set location on SyntaxError for try with both except and except* --- Grammar/python.gram | 4 ++-- Lib/test/test_syntax.py | 10 ++++++++++ Parser/parser.c | 18 +++++++++--------- 3 files changed, 21 insertions(+), 11 deletions(-) diff --git a/Grammar/python.gram b/Grammar/python.gram index 7dfc3df22fdd3c..2f251ce1ede154 100644 --- a/Grammar/python.gram +++ b/Grammar/python.gram @@ -1254,8 +1254,8 @@ invalid_try_stmt: | a='try' ':' NEWLINE !INDENT { RAISE_INDENTATION_ERROR("expected an indented block after 'try' statement on line %d", a->lineno) } | 'try' ':' block !('except' | 'finally') { RAISE_SYNTAX_ERROR("expected 'except' or 'finally' block") } - | 'try' ':' block* ((except_block+ except_star_block) | (except_star_block+ except_block)) block* { - RAISE_SYNTAX_ERROR("cannot have both 'except' and 'except*' on the same 'try'") } + | a='try' ':' block* ((except_block+ a=except_star_block) | (except_star_block+ a=except_block)) block* { + RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, "cannot have both 'except' and 'except*' on the same 'try'") } invalid_except_stmt: | 'except' '*'? a=expression ',' expressions ['as' NAME ] ':' { RAISE_SYNTAX_ERROR_STARTING_FROM(a, "multiple exception types must be parenthesized") } diff --git a/Lib/test/test_syntax.py b/Lib/test/test_syntax.py index b822bc9fc0a5b2..72538428f8ba41 100644 --- a/Lib/test/test_syntax.py +++ b/Lib/test/test_syntax.py @@ -2014,6 +2014,16 @@ def test_generator_in_function_call(self): "Generator expression must be parenthesized", lineno=1, end_lineno=1, offset=11, end_offset=53) + def test_except_then_except_star(self): + self._check_error("try: pass\nexcept ValueError: pass\nexcept* TypeError: pass", + r"cannot have both 'except' and 'except\*' on the same 'try'", + lineno=1, end_lineno=1, offset=1, end_offset=4) + + def test_except_star_then_except(self): + self._check_error("try: pass\nexcept* ValueError: pass\nexcept TypeError: pass", + r"cannot have both 'except' and 'except\*' on the same 'try'", + lineno=1, end_lineno=1, offset=1, end_offset=4) + def test_empty_line_after_linecont(self): # See issue-40847 s = r"""\ diff --git a/Parser/parser.c b/Parser/parser.c index b23507ac87c62e..c3da7bd3256446 100644 --- a/Parser/parser.c +++ b/Parser/parser.c @@ -21974,13 +21974,13 @@ invalid_try_stmt_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> invalid_try_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'try' ':' block* ((except_block+ except_star_block) | (except_star_block+ except_block)) block*")); - Token * _keyword; Token * _literal; asdl_seq * _loop0_203_var; asdl_seq * _loop0_205_var; void *_tmp_204_var; + Token * a; if ( - (_keyword = _PyPegen_expect_token(p, 620)) // token='try' + (a = _PyPegen_expect_token(p, 620)) // token='try' && (_literal = _PyPegen_expect_token(p, 11)) // token=':' && @@ -21992,7 +21992,7 @@ invalid_try_stmt_rule(Parser *p) ) { D(fprintf(stderr, "%*c+ invalid_try_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'try' ':' block* ((except_block+ except_star_block) | (except_star_block+ except_block)) block*")); - _res = RAISE_SYNTAX_ERROR ( "cannot have both 'except' and 'except*' on the same 'try'" ); + _res = RAISE_SYNTAX_ERROR_KNOWN_LOCATION ( a , "cannot have both 'except' and 'except*' on the same 'try'" ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; p->level--; @@ -38401,15 +38401,15 @@ _tmp_241_rule(Parser *p) } D(fprintf(stderr, "%*c> _tmp_241[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "except_block+ except_star_block")); asdl_seq * _loop1_248_var; - excepthandler_ty except_star_block_var; + excepthandler_ty a; if ( (_loop1_248_var = _loop1_248_rule(p)) // except_block+ && - (except_star_block_var = except_star_block_rule(p)) // except_star_block + (a = except_star_block_rule(p)) // except_star_block ) { D(fprintf(stderr, "%*c+ _tmp_241[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "except_block+ except_star_block")); - _res = _PyPegen_dummy_name(p, _loop1_248_var, except_star_block_var); + _res = _PyPegen_dummy_name(p, _loop1_248_var, a); goto done; } p->mark = _mark; @@ -38443,15 +38443,15 @@ _tmp_242_rule(Parser *p) } D(fprintf(stderr, "%*c> _tmp_242[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "except_star_block+ except_block")); asdl_seq * _loop1_249_var; - excepthandler_ty except_block_var; + excepthandler_ty a; if ( (_loop1_249_var = _loop1_249_rule(p)) // except_star_block+ && - (except_block_var = except_block_rule(p)) // except_block + (a = except_block_rule(p)) // except_block ) { D(fprintf(stderr, "%*c+ _tmp_242[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "except_star_block+ except_block")); - _res = _PyPegen_dummy_name(p, _loop1_249_var, except_block_var); + _res = _PyPegen_dummy_name(p, _loop1_249_var, a); goto done; } p->mark = _mark; From 633b06ea12b02c161dab98c613a8a929c0e95ea1 Mon Sep 17 00:00:00 2001 From: "blurb-it[bot]" <43283697+blurb-it[bot]@users.noreply.github.com> Date: Sun, 6 Nov 2022 13:25:04 +0000 Subject: [PATCH 2/4] =?UTF-8?q?=F0=9F=93=9C=F0=9F=A4=96=20Added=20by=20blu?= =?UTF-8?q?rb=5Fit.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../2022-11-06-13-25-01.gh-issue-99153.uE3CVL.rst | 1 + 1 file changed, 1 insertion(+) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2022-11-06-13-25-01.gh-issue-99153.uE3CVL.rst diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-11-06-13-25-01.gh-issue-99153.uE3CVL.rst b/Misc/NEWS.d/next/Core and Builtins/2022-11-06-13-25-01.gh-issue-99153.uE3CVL.rst new file mode 100644 index 00000000000000..9321af2b4a480e --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2022-11-06-13-25-01.gh-issue-99153.uE3CVL.rst @@ -0,0 +1 @@ +Fix location of :exc:`SyntaxError` for a :keyword:`try` block with both :keyword:`except` and :keyword:`except*`. From 3b9c604f3710fd96811444db946af2379b57a610 Mon Sep 17 00:00:00 2001 From: Irit Katriel Date: Sun, 6 Nov 2022 13:29:12 +0000 Subject: [PATCH 3/4] remove unused assignments --- Grammar/python.gram | 2 +- Parser/parser.c | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Grammar/python.gram b/Grammar/python.gram index 2f251ce1ede154..c947d22b99d422 100644 --- a/Grammar/python.gram +++ b/Grammar/python.gram @@ -1254,7 +1254,7 @@ invalid_try_stmt: | a='try' ':' NEWLINE !INDENT { RAISE_INDENTATION_ERROR("expected an indented block after 'try' statement on line %d", a->lineno) } | 'try' ':' block !('except' | 'finally') { RAISE_SYNTAX_ERROR("expected 'except' or 'finally' block") } - | a='try' ':' block* ((except_block+ a=except_star_block) | (except_star_block+ a=except_block)) block* { + | a='try' ':' block* ((except_block+ except_star_block) | (except_star_block+ except_block)) block* { RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, "cannot have both 'except' and 'except*' on the same 'try'") } invalid_except_stmt: | 'except' '*'? a=expression ',' expressions ['as' NAME ] ':' { diff --git a/Parser/parser.c b/Parser/parser.c index c3da7bd3256446..c2580556620d20 100644 --- a/Parser/parser.c +++ b/Parser/parser.c @@ -38401,15 +38401,15 @@ _tmp_241_rule(Parser *p) } D(fprintf(stderr, "%*c> _tmp_241[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "except_block+ except_star_block")); asdl_seq * _loop1_248_var; - excepthandler_ty a; + excepthandler_ty except_star_block_var; if ( (_loop1_248_var = _loop1_248_rule(p)) // except_block+ && - (a = except_star_block_rule(p)) // except_star_block + (except_star_block_var = except_star_block_rule(p)) // except_star_block ) { D(fprintf(stderr, "%*c+ _tmp_241[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "except_block+ except_star_block")); - _res = _PyPegen_dummy_name(p, _loop1_248_var, a); + _res = _PyPegen_dummy_name(p, _loop1_248_var, except_star_block_var); goto done; } p->mark = _mark; @@ -38443,15 +38443,15 @@ _tmp_242_rule(Parser *p) } D(fprintf(stderr, "%*c> _tmp_242[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "except_star_block+ except_block")); asdl_seq * _loop1_249_var; - excepthandler_ty a; + excepthandler_ty except_block_var; if ( (_loop1_249_var = _loop1_249_rule(p)) // except_star_block+ && - (a = except_block_rule(p)) // except_block + (except_block_var = except_block_rule(p)) // except_block ) { D(fprintf(stderr, "%*c+ _tmp_242[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "except_star_block+ except_block")); - _res = _PyPegen_dummy_name(p, _loop1_249_var, a); + _res = _PyPegen_dummy_name(p, _loop1_249_var, except_block_var); goto done; } p->mark = _mark; From 88eaf71fc60e51ea6d59632246eeec4bb1e0b27c Mon Sep 17 00:00:00 2001 From: Irit Katriel Date: Sun, 6 Nov 2022 13:46:21 +0000 Subject: [PATCH 4/4] fix formatting of news --- .../2022-11-06-13-25-01.gh-issue-99153.uE3CVL.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-11-06-13-25-01.gh-issue-99153.uE3CVL.rst b/Misc/NEWS.d/next/Core and Builtins/2022-11-06-13-25-01.gh-issue-99153.uE3CVL.rst index 9321af2b4a480e..0445afbbc4fb59 100644 --- a/Misc/NEWS.d/next/Core and Builtins/2022-11-06-13-25-01.gh-issue-99153.uE3CVL.rst +++ b/Misc/NEWS.d/next/Core and Builtins/2022-11-06-13-25-01.gh-issue-99153.uE3CVL.rst @@ -1 +1 @@ -Fix location of :exc:`SyntaxError` for a :keyword:`try` block with both :keyword:`except` and :keyword:`except*`. +Fix location of :exc:`SyntaxError` for a :keyword:`try` block with both :keyword:`except` and :keyword:`except* `.