-
Notifications
You must be signed in to change notification settings - Fork 1.3k
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] Single starred assignment target #17024
Conversation
Summary -- Detects starred assignment targets outside of tuples and lists like `*a = (1,)`. This PR only considers assignment statements. I also checked annotated assigment statements, but these give a separate error, so I think they're okay not to consider: ```pycon >>> *a: list[int] = [] File "<python-input-72>", line 1 *a: list[int] = [] ^ SyntaxError: invalid syntax ``` Fixes #13759 Test Plan -- New inline tests, plus a new `SemanticSyntaxError` for an existing parser test. I also removed a now-invalid case from an otherwise-valid test fixture. The new semantic error leads to two errors for the case below: ```python *foo() = 42 ``` but this matches [pyright] too. [pyright]: https://pyright-play.net/?code=FQMw9mAUCUAEC8sAsAmAUEA
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good apart from a couple minor comments!
Stmt::Assign(ast::StmtAssign { targets, .. }) => { | ||
// test_err single_starred_assignment_target | ||
// *a = (1,) | ||
|
||
// test_ok single_starred_assignment_target | ||
// (*a,) = (1,) | ||
// *a, = (1,) | ||
// [*a] = (1,) | ||
if let [Expr::Starred(ast::ExprStarred { range, .. })] = targets.as_slice() { | ||
Self::add_error( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think I'd find it useful to keep the test_err
closer to the add_error
calls, so I'd switch the test_err
and test_ok
comments around and move them right above the Self::add_error
call:
if let ... {
// test_ok ...
// test_err ...
Self::add_error(...)
}
| SemanticSyntaxErrorKind::IrrefutableCasePattern(_) | ||
| SemanticSyntaxErrorKind::SingleStarredAssignment | ||
if self.settings.preview.is_enabled() => | ||
{ | ||
self.semantic_errors.borrow_mut().push(error); | ||
} | ||
SemanticSyntaxErrorKind::ReboundComprehensionVariable | ||
| SemanticSyntaxErrorKind::DuplicateTypeParameter | ||
| SemanticSyntaxErrorKind::MultipleCaseAssignment(_) | ||
| SemanticSyntaxErrorKind::IrrefutableCasePattern(_) => {} | ||
| SemanticSyntaxErrorKind::IrrefutableCasePattern(_) | ||
| SemanticSyntaxErrorKind::SingleStarredAssignment => {} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I got a bit confused as to why there are multiple branches for the same variants 😅
I might be missing something, please correct me if I'm wrong but I'd suggest to move the preview check condition inside the case block to avoid repeating the variants:
SemanticSyntaxErrorKind::ReboundComprehensionVariable
| SemanticSyntaxErrorKind::DuplicateTypeParameter
| SemanticSyntaxErrorKind::MultipleCaseAssignment(_)
| SemanticSyntaxErrorKind::IrrefutableCasePattern(_)
| SemanticSyntaxErrorKind::SingleStarredAssignment => {
if self.settings.preview.is_enabled() {
self.semantic_errors.borrow_mut().push(error);
}
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this was a clippy suggestion when there was only one other variant, but it's definitely getting annoying to update them (and to read them!)
|
Summary
Detects starred assignment targets outside of tuples and lists like
*a = (1,)
.This PR only considers assignment statements. I also checked annotated assigment statements, but these give a separate error that we already catch, so I think they're okay not to consider:
Fixes #13759
Test Plan
New inline tests, plus a new
SemanticSyntaxError
for an existing parser test. I also removed a now-invalid case from an otherwise-valid test fixture.The new semantic error leads to two errors for the case below:
but this matches pyright too.