Skip to content

Commit

Permalink
Add syntax error for empty type parameter list (#12030)
Browse files Browse the repository at this point in the history
## Summary

(I'm pretty sure I added this in the parser re-write but must've got
lost in the rebase?)

This PR raises a syntax error if the type parameter list is empty.

As per the grammar, there should be at least one type parameter:
```
type_params: 
    | invalid_type_params
    | '[' type_param_seq ']' 

type_param_seq: ','.type_param+ [','] 
```

Verified via the builtin `ast` module as well:
```console    
$ python3.13 -m ast parser/_.py
Traceback (most recent call last):
  [..]
  File "parser/_.py", line 1
    def foo[]():
            ^
SyntaxError: Type parameter list cannot be empty
```

## Test Plan

Add inline test cases and update the snapshots.
  • Loading branch information
dhruvmanila committed Jun 26, 2024
1 parent 83fe447 commit 7cb2619
Show file tree
Hide file tree
Showing 4 changed files with 116 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
def foo[]():
pass
type ListOrSet[] = list | set
3 changes: 3 additions & 0 deletions crates/ruff_python_parser/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,8 @@ pub enum ParseErrorType {
EmptyDeleteTargets,
/// An empty import names list was found during parsing.
EmptyImportNames,
/// An empty type parameter list was found during parsing.
EmptyTypeParams,

/// An unparenthesized named expression was found where it is not allowed.
UnparenthesizedNamedExpression,
Expand Down Expand Up @@ -242,6 +244,7 @@ impl std::fmt::Display for ParseErrorType {
ParseErrorType::EmptyImportNames => {
f.write_str("Expected one or more symbol names after import")
}
ParseErrorType::EmptyTypeParams => f.write_str("Type parameter list cannot be empty"),
ParseErrorType::ParamAfterVarKeywordParam => {
f.write_str("Parameter cannot follow var-keyword parameter")
}
Expand Down
8 changes: 8 additions & 0 deletions crates/ruff_python_parser/src/parser/statement.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3027,6 +3027,14 @@ impl<'src> Parser<'src> {
Parser::parse_type_param,
);

if type_params.is_empty() {
// test_err type_params_empty
// def foo[]():
// pass
// type ListOrSet[] = list | set
self.add_error(ParseErrorType::EmptyTypeParams, self.current_token_range());
}

self.expect(TokenKind::Rsqb);

ast::TypeParams {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
---
source: crates/ruff_python_parser/tests/fixtures.rs
input_file: crates/ruff_python_parser/resources/inline/err/type_params_empty.py
---
## AST

```
Module(
ModModule {
range: 0..52,
body: [
FunctionDef(
StmtFunctionDef {
range: 0..21,
is_async: false,
decorator_list: [],
name: Identifier {
id: "foo",
range: 4..7,
},
type_params: Some(
TypeParams {
range: 7..9,
type_params: [],
},
),
parameters: Parameters {
range: 9..11,
posonlyargs: [],
args: [],
vararg: None,
kwonlyargs: [],
kwarg: None,
},
returns: None,
body: [
Pass(
StmtPass {
range: 17..21,
},
),
],
},
),
TypeAlias(
StmtTypeAlias {
range: 22..51,
name: Name(
ExprName {
range: 27..36,
id: "ListOrSet",
ctx: Store,
},
),
type_params: Some(
TypeParams {
range: 36..38,
type_params: [],
},
),
value: BinOp(
ExprBinOp {
range: 41..51,
left: Name(
ExprName {
range: 41..45,
id: "list",
ctx: Load,
},
),
op: BitOr,
right: Name(
ExprName {
range: 48..51,
id: "set",
ctx: Load,
},
),
},
),
},
),
],
},
)
```
## Errors

|
1 | def foo[]():
| ^ Syntax Error: Type parameter list cannot be empty
2 | pass
3 | type ListOrSet[] = list | set
|


|
1 | def foo[]():
2 | pass
3 | type ListOrSet[] = list | set
| ^ Syntax Error: Type parameter list cannot be empty
|

0 comments on commit 7cb2619

Please sign in to comment.