Skip to content

Commit 15acc4e

Browse files
authored
bpo-41659: Disallow curly brace directly after primary (GH-22996)
1 parent 95f710c commit 15acc4e

File tree

5 files changed

+244
-167
lines changed

5 files changed

+244
-167
lines changed

Grammar/python.gram

+3
Original file line numberDiff line numberDiff line change
@@ -475,6 +475,7 @@ await_primary[expr_ty] (memo):
475475
| AWAIT a=primary { CHECK_VERSION(expr_ty, 5, "Await expressions are", _Py_Await(a, EXTRA)) }
476476
| primary
477477
primary[expr_ty]:
478+
| invalid_primary # must be before 'primay genexp' because of invalid_genexp
478479
| a=primary '.' b=NAME { _Py_Attribute(a, b->v.Name.id, Load, EXTRA) }
479480
| a=primary b=genexp { _Py_Call(a, CHECK(asdl_expr_seq*, (asdl_expr_seq*)_PyPegen_singleton_seq(p, b)), NULL, EXTRA) }
480481
| a=primary '(' b=[arguments] ')' {
@@ -682,6 +683,8 @@ invalid_del_stmt:
682683
RAISE_SYNTAX_ERROR_INVALID_TARGET(DEL_TARGETS, a) }
683684
invalid_block:
684685
| NEWLINE !INDENT { RAISE_INDENTATION_ERROR("expected an indented block") }
686+
invalid_primary:
687+
| primary a='{' { RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, "invalid syntax") }
685688
invalid_comprehension:
686689
| ('[' | '(' | '{') a=starred_expression for_if_clauses {
687690
RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, "iterable unpacking cannot be used in comprehension") }

Lib/test/test_exceptions.py

+1
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,7 @@ def testSyntaxErrorOffset(self):
208208
check(b'Python = "\xcf\xb3\xf2\xee\xed" +', 1, 18)
209209
check('x = "a', 1, 7)
210210
check('lambda x: x = 2', 1, 1)
211+
check('f{a + b + c}', 1, 2)
211212

212213
# Errors thrown by compile.c
213214
check('class foo:return 1', 1, 11)

Lib/test/test_syntax.py

+3
Original file line numberDiff line numberDiff line change
@@ -802,6 +802,9 @@ def _check_error(self, code, errtext,
802802
else:
803803
self.fail("compile() did not raise SyntaxError")
804804

805+
def test_curly_brace_after_primary_raises_immediately(self):
806+
self._check_error("f{", "invalid syntax", mode="single")
807+
805808
def test_assign_call(self):
806809
self._check_error("f() = 1", "assign")
807810

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Fix a bug in the parser, where a curly brace following a `primary` didn't fail immediately.
2+
This led to invalid expressions like `a {b}` to throw a :exc:`SyntaxError` with a wrong offset,
3+
or invalid expressions ending with a curly brace like `a {` to not fail immediately in the REPL.

0 commit comments

Comments
 (0)