Skip to content

Commit b204fdb

Browse files
Replace simple_stmt_without_expressions with explicit invalid_ifexp_*
1 parent 6686090 commit b204fdb

File tree

3 files changed

+1180
-809
lines changed

3 files changed

+1180
-809
lines changed

Grammar/python.gram

Lines changed: 30 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -114,18 +114,15 @@ simple_stmt[stmt_ty] (memo):
114114
| assignment
115115
| &"type" type_alias
116116
| e=star_expressions { _PyAST_Expr(e, EXTRA) }
117-
| simple_stmt_without_expressions
118-
119-
simple_stmt_without_expressions[stmt_ty]:
120117
| &'return' return_stmt
121118
| &('import' | 'from') import_stmt
122119
| &'raise' raise_stmt
123-
| 'pass' { _PyAST_Pass(EXTRA) }
120+
| &'pass' pass_stmt
124121
| &'del' del_stmt
125122
| &'yield' yield_stmt
126123
| &'assert' assert_stmt
127-
| 'break' { _PyAST_Break(EXTRA) }
128-
| 'continue' { _PyAST_Continue(EXTRA) }
124+
| &'break' break_stmt
125+
| &'continue' continue_stmt
129126
| &'global' global_stmt
130127
| &'nonlocal' nonlocal_stmt
131128

@@ -184,6 +181,15 @@ raise_stmt[stmt_ty]:
184181
| 'raise' a=expression b=['from' z=expression { z }] { _PyAST_Raise(a, b, EXTRA) }
185182
| 'raise' { _PyAST_Raise(NULL, NULL, EXTRA) }
186183

184+
pass_stmt[stmt_ty]:
185+
| 'pass' { _PyAST_Pass(EXTRA) }
186+
187+
break_stmt[stmt_ty]:
188+
| 'break' { _PyAST_Break(EXTRA) }
189+
190+
continue_stmt[stmt_ty]:
191+
| 'continue' { _PyAST_Continue(EXTRA) }
192+
187193
global_stmt[stmt_ty]: 'global' a[asdl_expr_seq*]=','.NAME+ {
188194
_PyAST_Global(CHECK(asdl_identifier_seq*, _PyPegen_map_names_to_ids(p, a)), EXTRA) }
189195

@@ -1180,16 +1186,31 @@ invalid_type_param:
11801186
: "cannot use bound with ParamSpec")
11811187
}
11821188

1189+
invalid_ifexp_orelse_stmt[stmt_ty]:
1190+
| return_stmt
1191+
| raise_stmt
1192+
| pass_stmt
1193+
| del_stmt
1194+
| yield_stmt
1195+
| assert_stmt
1196+
| break_stmt
1197+
| continue_stmt
1198+
1199+
invalid_ifexp_body_stmt[stmt_ty]:
1200+
| pass_stmt
1201+
| break_stmt
1202+
| continue_stmt
1203+
11831204
invalid_expression:
11841205
# !(NAME STRING) is not matched so we don't show this error with some invalid string prefixes like: kf"dsfsdf"
11851206
# Soft keywords need to also be ignored because they can be parsed as NAME NAME
11861207
| !(NAME STRING | SOFT_KEYWORD) a=disjunction b=expression_without_invalid {
11871208
_PyPegen_check_legacy_stmt(p, a) ? NULL : p->tokens[p->mark-1]->level == 0 ? NULL :
11881209
RAISE_SYNTAX_ERROR_KNOWN_RANGE(a, b, "invalid syntax. Perhaps you forgot a comma?") }
11891210
| a=disjunction 'if' b=disjunction !('else'|':') { RAISE_SYNTAX_ERROR_KNOWN_RANGE(a, b, "expected 'else' after 'if' expression") }
1190-
| a=disjunction 'if' b=disjunction 'else' c=simple_stmt_without_expressions { RAISE_SYNTAX_ERROR_KNOWN_LOCATION (c, "statement given where 'orelse' expression required")}
1191-
| a=simple_stmt_without_expressions 'if' b=disjunction 'else' c=expression { RAISE_SYNTAX_ERROR_KNOWN_LOCATION (a, "statement given where 'body' expression required")}
1192-
| a=simple_stmt_without_expressions 'if' b=disjunction 'else' c=simple_stmt_without_expressions { RAISE_SYNTAX_ERROR_KNOWN_LOCATION (a, "statement given where 'body' expression required")}
1211+
| a=disjunction 'if' b=disjunction 'else' c=invalid_ifexp_orelse_stmt { RAISE_SYNTAX_ERROR_KNOWN_LOCATION (c, "statement given where 'orelse' expression required")}
1212+
| a=invalid_ifexp_body_stmt 'if' b=disjunction 'else' c=expression { RAISE_SYNTAX_ERROR_KNOWN_LOCATION (a, "statement given where 'body' expression required")}
1213+
| a=invalid_ifexp_body_stmt 'if' b=disjunction 'else' c=invalid_ifexp_orelse_stmt { RAISE_SYNTAX_ERROR_KNOWN_LOCATION (a, "statement given where 'body' expression required")}
11931214
| a='lambda' [lambda_params] b=':' &FSTRING_MIDDLE {
11941215
RAISE_SYNTAX_ERROR_KNOWN_RANGE(a, b, "f-string: lambda expressions are not allowed without parentheses") }
11951216

Lib/test/test_ast/test_ast.py

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1987,26 +1987,14 @@ def test_ifexp_orelse_stmt(self):
19871987
def test_ifexp_body_stmt_orelse_expression(self):
19881988
with self.assertRaisesRegex(SyntaxError, "statement given where 'body' expression required"):
19891989
ast.parse("x = pass if 1 else 1")
1990-
with self.assertRaisesRegex(SyntaxError, "statement given where 'body' expression required"):
1991-
ast.parse("x = return if 1 else 1")
1992-
with self.assertRaisesRegex(SyntaxError, "statement given where 'body' expression required"):
1993-
ast.parse("x = raise if 1 else 1")
19941990
with self.assertRaisesRegex(SyntaxError, "statement given where 'body' expression required"):
19951991
ast.parse("x = break if 1 else 1")
19961992
with self.assertRaisesRegex(SyntaxError, "statement given where 'body' expression required"):
19971993
ast.parse("x = continue if 1 else 1")
19981994

1999-
# this is not covered by 'invalid_expression' rule
2000-
with self.assertRaisesRegex(SyntaxError, "cannot delete conditional expression"):
2001-
ast.parse("a = 1; x = del a if 1 else 1")
2002-
20031995
def test_ifexp_body_stmt_orelse_stmt(self):
20041996
with self.assertRaisesRegex(SyntaxError, "statement given where 'body' expression required"):
20051997
ast.parse("x = pass if 1 else pass")
2006-
with self.assertRaisesRegex(SyntaxError, "statement given where 'body' expression required"):
2007-
ast.parse("x = return if 1 else pass")
2008-
with self.assertRaisesRegex(SyntaxError, "statement given where 'body' expression required"):
2009-
ast.parse("x = raise if 1 else pass")
20101998
with self.assertRaisesRegex(SyntaxError, "statement given where 'body' expression required"):
20111999
ast.parse("x = break if 1 else pass")
20122000
with self.assertRaisesRegex(SyntaxError, "statement given where 'body' expression required"):

0 commit comments

Comments
 (0)