Skip to content

Commit

Permalink
Fix typo and broken test cases (#102)
Browse files Browse the repository at this point in the history
* Fix typo

* Update test cases

* fix(follow Python 3.12.4):

* style: fix black lint complains
  • Loading branch information
yf-yang authored Jun 20, 2024
1 parent 3cefc85 commit dc7543e
Show file tree
Hide file tree
Showing 7 changed files with 49 additions and 30 deletions.
7 changes: 4 additions & 3 deletions data/python.gram
Original file line number Diff line number Diff line change
Expand Up @@ -1805,6 +1805,7 @@ kwargs[list]:
starred_expression:
| invalid_starred_expression
| '*' a=expression { ast.Starred(value=a, ctx=Load, LOCATIONS) }
| '*' { self.raise_syntax_error("Invalid star expression") }

kwarg_or_starred:
| invalid_kwarg
Expand Down Expand Up @@ -1921,10 +1922,10 @@ func_type_comment:

# From here on, there are rules for invalid syntax with specialised error messages
invalid_arguments[NoReturn]:
| a=args ',' '*' {
self.raise_syntax_error_known_location(
| ((','.(starred_expression | ( assignment_expression | expression !':=') !'=')+ ',' kwargs) | kwargs) a=',' ','.(starred_expression !'=')+ {
self.raise_syntax_error_starting_from(
"iterable argument unpacking follows keyword argument unpacking",
a[1][-1] if a[1] else a[0][-1],
a,
)
}
| a=expression b=for_if_clauses ',' [args | expression for_if_clauses] {
Expand Down
4 changes: 2 additions & 2 deletions src/pegen/parser_generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ def collect_todo(self) -> None:
self.todo[rulename].collect_todo(self)
done = set(alltodo)

def artifical_rule_from_rhs(self, rhs: Rhs) -> str:
def artificial_rule_from_rhs(self, rhs: Rhs) -> str:
self.counter += 1
name = f"_tmp_{self.counter}" # TODO: Pick a nicer name.
self.todo[name] = Rule(name, None, rhs)
Expand All @@ -129,7 +129,7 @@ def artificial_rule_from_repeat(self, node: Plain, is_repeat1: bool) -> str:
self.todo[name] = Rule(name, None, Rhs([Alt([NamedItem(None, node)])]))
return name

def artifical_rule_from_gather(self, node: Gather) -> str:
def artificial_rule_from_gather(self, node: Gather) -> str:
self.counter += 1
name = f"_gather_{self.counter}"
self.counter += 1
Expand Down
4 changes: 2 additions & 2 deletions src/pegen/python_generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ def visit_Rhs(self, node: Rhs) -> Tuple[Optional[str], str]:
if len(node.alts) == 1 and len(node.alts[0].items) == 1:
self.cache[node] = self.visit(node.alts[0].items[0])
else:
name = self.gen.artifical_rule_from_rhs(node)
name = self.gen.artificial_rule_from_rhs(node)
self.cache[node] = name, f"self.{name}()"
return self.cache[node]

Expand Down Expand Up @@ -186,7 +186,7 @@ def visit_Repeat1(self, node: Repeat1) -> Tuple[str, str]:
def visit_Gather(self, node: Gather) -> Tuple[str, str]:
if node in self.cache:
return self.cache[node]
name = self.gen.artifical_rule_from_gather(node)
name = self.gen.artificial_rule_from_gather(node)
self.cache[node] = name, f"self.{name}()" # No trailing comma here either!
return self.cache[node]

Expand Down
1 change: 1 addition & 0 deletions tests/python_parser/conftest.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
""""Conftest for pure python parser."""

from pathlib import Path

import pytest
Expand Down
1 change: 1 addition & 0 deletions tests/python_parser/test_ast_parsing.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Test pure Python parser against cpython parser."""

import ast
import difflib
import io
Expand Down
61 changes: 38 additions & 23 deletions tests/python_parser/test_syntax_error_handling.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Test syntax errors for cases where the parser can generate helpful messages."""

import sys

import pytest
Expand Down Expand Up @@ -93,57 +94,71 @@ def parse_invalid_syntax(
[
(
"f'a = {}'",
"valid expression required before '}'"
if sys.version_info >= (3, 12)
else "f-string: empty expression not allowed",
(
"valid expression required before '}'"
if sys.version_info >= (3, 12)
else "f-string: empty expression not allowed"
),
(1, 8) if sys.version_info >= (3, 12) else None,
(1, 9) if sys.version_info >= (3, 12) else None,
),
(
"f'a = {=}'",
"expression required before '='"
if sys.version_info >= (3, 11)
else "f-string: empty expression not allowed",
(
"expression required before '='"
if sys.version_info >= (3, 11)
else "f-string: empty expression not allowed"
),
(1, 8) if sys.version_info >= (3, 12) else None,
(1, 9) if sys.version_info >= (3, 12) else None,
),
(
"f'a = {!}'",
"expression required before '!'"
if sys.version_info >= (3, 11)
else "f-string: empty expression not allowed",
(
"expression required before '!'"
if sys.version_info >= (3, 11)
else "f-string: empty expression not allowed"
),
(1, 8) if sys.version_info >= (3, 12) else None,
(1, 9) if sys.version_info >= (3, 12) else None,
),
(
"f'a = {:}'",
"expression required before ':'"
if sys.version_info >= (3, 11)
else "f-string: empty expression not allowed",
(
"expression required before ':'"
if sys.version_info >= (3, 11)
else "f-string: empty expression not allowed"
),
(1, 8) if sys.version_info >= (3, 12) else None,
(1, 9) if sys.version_info >= (3, 12) else (1, 11),
),
(
"f'a = {a=d}'",
"expecting '!', or ':', or '}'"
if sys.version_info >= (3, 12)
else "f-string: expecting '}'",
(
"expecting '!', or ':', or '}'"
if sys.version_info >= (3, 12)
else "f-string: expecting '}'"
),
(1, 10) if sys.version_info >= (3, 12) else None,
(1, 11) if sys.version_info >= (3, 12) else None,
),
(
"f'a = { 1 + }'",
"f-string: expecting '=', or '!', or ':', or '}'"
if sys.version_info >= (3, 12)
else "f-string: invalid syntax",
(
"f-string: expecting '=', or '!', or ':', or '}'"
if sys.version_info >= (3, 12)
else "f-string: invalid syntax"
),
(1, 11) if sys.version_info >= (3, 12) else (1, 7),
(1, 12) if sys.version_info >= (3, 12) else (1, 8),
),
(
"(\n\t'b'\n\tf'a = { 1 + }'\n)",
"f-string: expecting '=', or '!', or ':', or '}'"
if sys.version_info >= (3, 12)
else "f-string: invalid syntax",
(
"f-string: expecting '=', or '!', or ':', or '}'"
if sys.version_info >= (3, 12)
else "f-string: invalid syntax"
),
(3, 12) if sys.version_info >= (3, 12) else (3, 7),
(3, 13) if sys.version_info >= (3, 12) else (3, 8),
),
Expand Down Expand Up @@ -210,8 +225,8 @@ def test_invalid_statements(
(
"f(**a, *b)",
"iterable argument unpacking follows keyword argument unpacking",
(1, 3),
(1, 6),
(1, 6) if sys.version_info >= (3, 12) else None,
(1, 10) if sys.version_info >= (3, 12) else None,
),
# NOTE CPython bug, should report 15 as expected (we use None to omit the check)
("f(a for a in b, c)", "Generator expression must be parenthesized", (1, 3), (1, None)),
Expand Down
1 change: 1 addition & 0 deletions tests/python_parser/test_unsupported_syntax.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
not broader since we would not be able to generate the proper ast nodes.
"""

import io
import tokenize

Expand Down

0 comments on commit dc7543e

Please sign in to comment.