Skip to content

Commit c4b58ce

Browse files
authored
[3.9] bpo-41659: Disallow curly brace directly after primary (GH-22996) (#23006)
(cherry picked from commit 15acc4e)
1 parent 8aee019 commit c4b58ce

File tree

5 files changed

+244
-167
lines changed

5 files changed

+244
-167
lines changed

Grammar/python.gram

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -460,6 +460,7 @@ await_primary[expr_ty] (memo):
460460
| AWAIT a=primary { CHECK_VERSION(5, "Await expressions are", _Py_Await(a, EXTRA)) }
461461
| primary
462462
primary[expr_ty]:
463+
| invalid_primary # must be before 'primay genexp' because of invalid_genexp
463464
| a=primary '.' b=NAME { _Py_Attribute(a, b->v.Name.id, Load, EXTRA) }
464465
| a=primary b=genexp { _Py_Call(a, CHECK(_PyPegen_singleton_seq(p, b)), NULL, EXTRA) }
465466
| a=primary '(' b=[arguments] ')' {
@@ -664,6 +665,8 @@ invalid_del_stmt:
664665
RAISE_SYNTAX_ERROR_INVALID_TARGET(DEL_TARGETS, a) }
665666
invalid_block:
666667
| NEWLINE !INDENT { RAISE_INDENTATION_ERROR("expected an indented block") }
668+
invalid_primary:
669+
| primary a='{' { RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, "invalid syntax") }
667670
invalid_comprehension:
668671
| ('[' | '(' | '{') a=starred_expression for_if_clauses {
669672
RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, "iterable unpacking cannot be used in comprehension") }

Lib/test/test_exceptions.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,7 @@ def testSyntaxErrorOffset(self):
205205
check(b'Python = "\xcf\xb3\xf2\xee\xed" +', 1, 18)
206206
check('x = "a', 1, 7)
207207
check('lambda x: x = 2', 1, 1)
208+
check('f{a + b + c}', 1, 2)
208209

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

Lib/test/test_syntax.py

Lines changed: 3 additions & 0 deletions
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

Lines changed: 3 additions & 0 deletions
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)