[syntax-errors] Detect single starred expression assignment x = *y (#17624)

## Summary

Part of #17412

Starred expressions cannot be used as values in assignment expressions.
Add a new semantic syntax error to catch such instances.
Note that we already have
`ParseErrorType::InvalidStarredExpressionUsage` to catch some starred
expression errors during parsing, but that does not cover top level
assignment expressions.

## Test Plan

- Added new inline tests for the new rule
- Found some examples marked as "valid" in existing tests (`_ = *data`),
which are not really valid (per this new rule) and updated them
- There was an existing inline test - `assign_stmt_invalid_value_expr`
which had instances of `*` expression which would be deemed invalid by
this new rule. Converted these to tuples, so that they do not trigger
this new rule.
This commit is contained in:
Abhijeet Prasad Bodas 2025-05-01 00:34:00 +05:30 committed by GitHub
parent f31b1c695c
commit 0eeb02c0c1
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
10 changed files with 661 additions and 217 deletions

View file

@ -1127,10 +1127,10 @@ impl<'src> Parser<'src> {
// a + b
// test_err assign_stmt_invalid_value_expr
// x = *a and b
// x = *yield x
// x = *yield from x
// x = *lambda x: x
// x = (*a and b,)
// x = (42, *yield x)
// x = (42, *yield from x)
// x = (*lambda x: x,)
// x = x := 1
let mut value =

View file

@ -90,7 +90,7 @@ impl SemanticSyntaxChecker {
Self::duplicate_type_parameter_name(type_params, ctx);
}
}
Stmt::Assign(ast::StmtAssign { targets, .. }) => {
Stmt::Assign(ast::StmtAssign { targets, value, .. }) => {
if let [Expr::Starred(ast::ExprStarred { range, .. })] = targets.as_slice() {
// test_ok single_starred_assignment_target
// (*a,) = (1,)
@ -105,6 +105,19 @@ impl SemanticSyntaxChecker {
*range,
);
}
// test_ok assign_stmt_starred_expr_value
// _ = 4
// _ = [4]
// _ = (*[1],)
// _ = *[1],
// test_err assign_stmt_starred_expr_value
// _ = *[42]
// _ = *{42}
// _ = *list()
// _ = *(p + q)
Self::invalid_star_expression(value, ctx);
}
Stmt::Return(ast::StmtReturn { value, range }) => {
if let Some(value) = value {