Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[syntax-errors] type statements before Python 3.12 #16478

Merged
merged 7 commits into from
Mar 4, 2025
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# parse_options: {"target-version": "3.11"}
type x = int
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# parse_options: {"target-version": "3.12"}
type x = int
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 @@ -449,6 +449,7 @@ pub enum UnsupportedSyntaxErrorKind {
Match,
Walrus,
ExceptStar,
TypeStmt,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we use type alias instead of type statement? I would find this more approachable as a user, unless the term is ambiguous.

Suggested change
TypeStmt,
TypeAlias,

https://docs.python.org/3/library/typing.html#type-aliases

If not TypeAlias, then rename to TypeStatement

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pyright calls them "type alias statements," which I think sounds good for the user-facing message. For the variant name, I don't have strong feelings either way. They do call it a type_stmt in the Python reference, so I might lean toward TypeStatement if you prefer that to Stmt.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll just call it TypeAliasStatement, I see that's what we call the parser function now.

}

impl Display for UnsupportedSyntaxError {
Expand All @@ -457,6 +458,7 @@ impl Display for UnsupportedSyntaxError {
UnsupportedSyntaxErrorKind::Match => "`match` statement",
UnsupportedSyntaxErrorKind::Walrus => "named assignment expression (`:=`)",
UnsupportedSyntaxErrorKind::ExceptStar => "`except*`",
UnsupportedSyntaxErrorKind::TypeStmt => "`type` statement",
};
write!(
f,
Expand All @@ -474,6 +476,7 @@ impl UnsupportedSyntaxErrorKind {
UnsupportedSyntaxErrorKind::Match => PythonVersion::PY310,
UnsupportedSyntaxErrorKind::Walrus => PythonVersion::PY38,
UnsupportedSyntaxErrorKind::ExceptStar => PythonVersion::PY311,
UnsupportedSyntaxErrorKind::TypeStmt => PythonVersion::PY312,
}
}
}
Expand Down
12 changes: 12 additions & 0 deletions crates/ruff_python_parser/src/parser/statement.rs
Original file line number Diff line number Diff line change
Expand Up @@ -890,6 +890,8 @@ impl<'src> Parser<'src> {
let start = self.node_start();
self.bump(TokenKind::Type);

let type_range = self.node_range(start);

let mut name = Expr::Name(self.parse_name());
helpers::set_expr_ctx(&mut name, ExprContext::Store);

Expand All @@ -909,6 +911,16 @@ impl<'src> Parser<'src> {
// type x = x := 1
let value = self.parse_conditional_expression_or_higher();

// test_ok type_stmt_py312
// # parse_options: {"target-version": "3.12"}
// type x = int

// test_err type_stmt_py311
// # parse_options: {"target-version": "3.11"}
// type x = int

self.add_unsupported_syntax_error(UnsupportedSyntaxErrorKind::TypeStmt, type_range);

ast::StmtTypeAlias {
name: Box::new(name),
type_params,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
---
source: crates/ruff_python_parser/tests/fixtures.rs
input_file: crates/ruff_python_parser/resources/inline/err/type_stmt_py311.py
---
## AST

```
Module(
ModModule {
range: 0..57,
body: [
TypeAlias(
StmtTypeAlias {
range: 44..56,
name: Name(
ExprName {
range: 49..50,
id: Name("x"),
ctx: Store,
},
),
type_params: None,
value: Name(
ExprName {
range: 53..56,
id: Name("int"),
ctx: Load,
},
),
},
),
],
},
)
```
## Unsupported Syntax Errors

|
1 | # parse_options: {"target-version": "3.11"}
2 | type x = int
| ^^^^ Syntax Error: Cannot use `type` statement on Python 3.11 (syntax was added in Python 3.12)
|
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
---
source: crates/ruff_python_parser/tests/fixtures.rs
input_file: crates/ruff_python_parser/resources/inline/ok/type_stmt_py312.py
---
## AST

```
Module(
ModModule {
range: 0..57,
body: [
TypeAlias(
StmtTypeAlias {
range: 44..56,
name: Name(
ExprName {
range: 49..50,
id: Name("x"),
ctx: Store,
},
),
type_params: None,
value: Name(
ExprName {
range: 53..56,
id: Name("int"),
ctx: Load,
},
),
},
),
],
},
)
```
Loading