Skip to content

Commit

Permalink
pythongh-125326: Improve SyntaxError for invalid type params definiton
Browse files Browse the repository at this point in the history
  • Loading branch information
sobolevn committed Oct 12, 2024
1 parent 5d8739e commit 150a28a
Show file tree
Hide file tree
Showing 4 changed files with 485 additions and 295 deletions.
36 changes: 28 additions & 8 deletions Grammar/python.gram
Original file line number Diff line number Diff line change
Expand Up @@ -649,9 +649,10 @@ type_param_seq[asdl_type_param_seq*]: a[asdl_type_param_seq*]=','.type_param+ ['

type_param[type_param_ty] (memo):
| a=NAME b=[type_param_bound] c=[type_param_default] { _PyAST_TypeVar(a->v.Name.id, b, c, EXTRA) }
| invalid_type_param
| invalid_type_param_def
| '*' a=NAME b=[type_param_starred_default] { _PyAST_TypeVarTuple(a->v.Name.id, b, EXTRA) }
| '**' a=NAME b=[type_param_default] { _PyAST_ParamSpec(a->v.Name.id, b, EXTRA) }
| invalid_type_param_expr

type_param_bound[expr_ty]: ':' e=expression { e }
type_param_default[expr_ty]: '=' e=expression {
Expand Down Expand Up @@ -1165,7 +1166,15 @@ invalid_legacy_expression:
_PyPegen_check_legacy_stmt(p, a) ? RAISE_SYNTAX_ERROR_KNOWN_RANGE(a, b,
"Missing parentheses in call to '%U'. Did you mean %U(...)?", a->v.Name.id, a->v.Name.id) : NULL}

invalid_type_param:
# Invalid type parameters:

invalid_type_params:
| '[' token=']' {
RAISE_SYNTAX_ERROR_STARTING_FROM(
token,
"Type parameter list cannot be empty")}

invalid_type_param_def:
| '*' a=NAME colon=':' e=expression {
RAISE_SYNTAX_ERROR_STARTING_FROM(colon, e->kind == Tuple_kind
? "cannot use constraints with TypeVarTuple"
Expand All @@ -1177,6 +1186,23 @@ invalid_type_param:
: "cannot use bound with ParamSpec")
}

invalid_type_param_expr:
| a=expression [type_param_bound] [type_param_default] {
RAISE_SYNTAX_ERROR_KNOWN_LOCATION(
a, "expected a type parameter definition, found %s",
_PyPegen_get_expr_name(a))
}
| '*' a=expression [type_param_starred_default] {
RAISE_SYNTAX_ERROR_KNOWN_LOCATION(
a, "expected a type parameter definition, found %s",
_PyPegen_get_expr_name(a))
}
| '**' a=expression [type_param_default] {
RAISE_SYNTAX_ERROR_KNOWN_LOCATION(
a, "expected a type parameter definition, found %s",
_PyPegen_get_expr_name(a))
}

invalid_expression:
# !(NAME STRING) is not matched so we don't show this error with some invalid string prefixes like: kf"dsfsdf"
# Soft keywords need to also be ignored because they can be parsed as NAME NAME
Expand Down Expand Up @@ -1453,9 +1479,3 @@ invalid_arithmetic:
| sum ('+'|'-'|'*'|'/'|'%'|'//'|'@') a='not' b=inversion { RAISE_SYNTAX_ERROR_KNOWN_RANGE(a, b, "'not' after an operator must be parenthesized") }
invalid_factor:
| ('+' | '-' | '~') a='not' b=factor { RAISE_SYNTAX_ERROR_KNOWN_RANGE(a, b, "'not' after an operator must be parenthesized") }

invalid_type_params:
| '[' token=']' {
RAISE_SYNTAX_ERROR_STARTING_FROM(
token,
"Type parameter list cannot be empty")}
30 changes: 30 additions & 0 deletions Lib/test/test_syntax.py
Original file line number Diff line number Diff line change
Expand Up @@ -2175,6 +2175,36 @@ def f(x: *b)
...
SyntaxError: Type parameter list cannot be empty
>>> type A[1] = ...
Traceback (most recent call last):
...
SyntaxError: expected a type parameter definition, found literal
>>> type A[*()] = ...
Traceback (most recent call last):
...
SyntaxError: expected a type parameter definition, found tuple
>>> type A[**{}] = ...
Traceback (most recent call last):
...
SyntaxError: expected a type parameter definition, found dict literal
>>> def some["abc"](): ...
Traceback (most recent call last):
...
SyntaxError: expected a type parameter definition, found literal
>>> class Some[*...]: ...
Traceback (most recent call last):
...
SyntaxError: expected a type parameter definition, found ellipsis
>>> async def some[**{}](): ...
Traceback (most recent call last):
...
SyntaxError: expected a type parameter definition, found dict literal
>>> def f[T: (x:=3)](): pass
Traceback (most recent call last):
...
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Improve :exc:`SyntaxError` message for using invalid type parameters
definition.
Loading

0 comments on commit 150a28a

Please sign in to comment.