Skip to content

Commit 78234d2

Browse files
committed
bpo-45834: Move runtime 'except:' check to the parser
1 parent 9bf2cbc commit 78234d2

File tree

5 files changed

+1198
-829
lines changed

5 files changed

+1198
-829
lines changed

Grammar/python.gram

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -402,7 +402,12 @@ with_item[withitem_ty]:
402402
try_stmt[stmt_ty]:
403403
| invalid_try_stmt
404404
| 'try' &&':' b=block f=finally_block { _PyAST_Try(b, NULL, NULL, f, EXTRA) }
405-
| 'try' &&':' b=block ex[asdl_excepthandler_seq*]=except_block+ el=[else_block] f=[finally_block] { _PyAST_Try(b, ex, el, f, EXTRA) }
405+
| 'try' &&':' b=block ex[asdl_excepthandler_seq*]=except_block+ d_ex[asdl_match_case_seq*]=[default_except_block] el=[else_block] f=[finally_block] {
406+
_PyAST_Try(b, (d_ex) ? (asdl_excepthandler_seq*)_PyPegen_seq_append_to_end(p, (asdl_seq*)ex, d_ex) : ex, el, f, EXTRA)
407+
}
408+
| 'try' &&':' b=block d_ex[asdl_match_case_seq*]=default_except_block el=[else_block] f=[finally_block] {
409+
_PyAST_Try(b, (asdl_excepthandler_seq*)_PyPegen_singleton_seq(p, d_ex), el, f, EXTRA)
410+
}
406411

407412
# Except statement
408413
# ----------------
@@ -411,8 +416,9 @@ except_block[excepthandler_ty]:
411416
| invalid_except_stmt_indent
412417
| 'except' e=expression t=['as' z=NAME { z }] ':' b=block {
413418
_PyAST_ExceptHandler(e, (t) ? ((expr_ty) t)->v.Name.id : NULL, b, EXTRA) }
414-
| 'except' ':' b=block { _PyAST_ExceptHandler(NULL, NULL, b, EXTRA) }
415419
| invalid_except_stmt
420+
default_except_block[excepthandler_ty]:
421+
| 'except' ':' b=block { _PyAST_ExceptHandler(NULL, NULL, b, EXTRA) }
416422
finally_block[asdl_stmt_seq*]:
417423
| invalid_finally_stmt
418424
| 'finally' &&':' a=block { a }
@@ -1187,6 +1193,9 @@ invalid_try_stmt:
11871193
| a='try' ':' NEWLINE !INDENT {
11881194
RAISE_INDENTATION_ERROR("expected an indented block after 'try' statement on line %d", a->lineno) }
11891195
| 'try' ':' block !('except' | 'finally') { RAISE_SYNTAX_ERROR("expected 'except' or 'finally' block") }
1196+
| 'try' ':' block except_block* a=default_except_block (except_block|default_except_block)+ {
1197+
RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, "default 'except:' must be last") }
1198+
11901199
invalid_except_stmt:
11911200
| 'except' a=expression ',' expressions ['as' NAME ] ':' {
11921201
RAISE_SYNTAX_ERROR_STARTING_FROM(a, "multiple exception types must be parenthesized") }

Lib/test/test_syntax.py

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1039,6 +1039,49 @@
10391039
Traceback (most recent call last):
10401040
IndentationError: expected an indented block after 'finally' statement on line 5
10411041
1042+
>>> try:
1043+
... something()
1044+
... except:
1045+
... pass
1046+
... except A:
1047+
... pass
1048+
... else:
1049+
... pass
1050+
... finally:
1051+
... pass
1052+
Traceback (most recent call last):
1053+
SyntaxError: default 'except:' must be last
1054+
1055+
>>> try:
1056+
... something()
1057+
... except:
1058+
... pass
1059+
... except:
1060+
... pass
1061+
... else:
1062+
... pass
1063+
... finally:
1064+
... pass
1065+
Traceback (most recent call last):
1066+
SyntaxError: default 'except:' must be last
1067+
1068+
>>> try:
1069+
... something()
1070+
... except A:
1071+
... pass
1072+
... except B:
1073+
... pass
1074+
... except:
1075+
... pass
1076+
... except C:
1077+
... pass
1078+
... else:
1079+
... pass
1080+
... finally:
1081+
... pass
1082+
Traceback (most recent call last):
1083+
SyntaxError: default 'except:' must be last
1084+
10421085
>>> with A:
10431086
... pass
10441087
Traceback (most recent call last):

0 commit comments

Comments
 (0)