mirror of
https://github.com/astral-sh/ruff.git
synced 2025-09-29 13:24:57 +00:00
[syntax-errors]: multiple-starred-expressions (F622) (#20243)
<!-- Thank you for contributing to Ruff/ty! To help us out with reviewing, please consider the following: - Does this pull request include a summary of the change? (See below.) - Does this pull request include a descriptive title? (Please prefix with `[ty]` for ty pull requests.) - Does this pull request include references to any relevant issues? --> ## Summary This PR implements https://docs.astral.sh/ruff/rules/multiple-starred-expressions/ as a semantic syntax error ## Test Plan I have added inline tests as directed in #17412 --------- Signed-off-by: 11happy <soni5happy@gmail.com> Co-authored-by: Brent Westbrook <36778786+ntBre@users.noreply.github.com>
This commit is contained in:
parent
73b4b1ed17
commit
e6073d0cca
8 changed files with 783 additions and 20 deletions
|
@ -212,13 +212,10 @@ pub(crate) fn expression(expr: &Expr, checker: &Checker) {
|
||||||
if ctx.is_store() {
|
if ctx.is_store() {
|
||||||
let check_too_many_expressions =
|
let check_too_many_expressions =
|
||||||
checker.is_rule_enabled(Rule::ExpressionsInStarAssignment);
|
checker.is_rule_enabled(Rule::ExpressionsInStarAssignment);
|
||||||
let check_two_starred_expressions =
|
|
||||||
checker.is_rule_enabled(Rule::MultipleStarredExpressions);
|
|
||||||
pyflakes::rules::starred_expressions(
|
pyflakes::rules::starred_expressions(
|
||||||
checker,
|
checker,
|
||||||
elts,
|
elts,
|
||||||
check_too_many_expressions,
|
check_too_many_expressions,
|
||||||
check_two_starred_expressions,
|
|
||||||
expr.range(),
|
expr.range(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -69,8 +69,8 @@ use crate::package::PackageRoot;
|
||||||
use crate::preview::is_undefined_export_in_dunder_init_enabled;
|
use crate::preview::is_undefined_export_in_dunder_init_enabled;
|
||||||
use crate::registry::Rule;
|
use crate::registry::Rule;
|
||||||
use crate::rules::pyflakes::rules::{
|
use crate::rules::pyflakes::rules::{
|
||||||
LateFutureImport, ReturnOutsideFunction, UndefinedLocalWithNestedImportStarUsage,
|
LateFutureImport, MultipleStarredExpressions, ReturnOutsideFunction,
|
||||||
YieldOutsideFunction,
|
UndefinedLocalWithNestedImportStarUsage, YieldOutsideFunction,
|
||||||
};
|
};
|
||||||
use crate::rules::pylint::rules::{
|
use crate::rules::pylint::rules::{
|
||||||
AwaitOutsideAsync, LoadBeforeGlobalDeclaration, YieldFromInAsyncFunction,
|
AwaitOutsideAsync, LoadBeforeGlobalDeclaration, YieldFromInAsyncFunction,
|
||||||
|
@ -685,6 +685,12 @@ impl SemanticSyntaxContext for Checker<'_> {
|
||||||
self.report_diagnostic(YieldFromInAsyncFunction, error.range);
|
self.report_diagnostic(YieldFromInAsyncFunction, error.range);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
SemanticSyntaxErrorKind::MultipleStarredExpressions => {
|
||||||
|
// F622
|
||||||
|
if self.is_rule_enabled(Rule::MultipleStarredExpressions) {
|
||||||
|
self.report_diagnostic(MultipleStarredExpressions, error.range);
|
||||||
|
}
|
||||||
|
}
|
||||||
SemanticSyntaxErrorKind::ReboundComprehensionVariable
|
SemanticSyntaxErrorKind::ReboundComprehensionVariable
|
||||||
| SemanticSyntaxErrorKind::DuplicateTypeParameter
|
| SemanticSyntaxErrorKind::DuplicateTypeParameter
|
||||||
| SemanticSyntaxErrorKind::MultipleCaseAssignment(_)
|
| SemanticSyntaxErrorKind::MultipleCaseAssignment(_)
|
||||||
|
|
|
@ -53,27 +53,14 @@ impl Violation for MultipleStarredExpressions {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// F621, F622
|
/// F621
|
||||||
pub(crate) fn starred_expressions(
|
pub(crate) fn starred_expressions(
|
||||||
checker: &Checker,
|
checker: &Checker,
|
||||||
elts: &[Expr],
|
elts: &[Expr],
|
||||||
check_too_many_expressions: bool,
|
check_too_many_expressions: bool,
|
||||||
check_two_starred_expressions: bool,
|
|
||||||
location: TextRange,
|
location: TextRange,
|
||||||
) {
|
) {
|
||||||
let mut has_starred: bool = false;
|
let starred_index: Option<usize> = None;
|
||||||
let mut starred_index: Option<usize> = None;
|
|
||||||
for (index, elt) in elts.iter().enumerate() {
|
|
||||||
if elt.is_starred_expr() {
|
|
||||||
if has_starred && check_two_starred_expressions {
|
|
||||||
checker.report_diagnostic(MultipleStarredExpressions, location);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
has_starred = true;
|
|
||||||
starred_index = Some(index);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if check_too_many_expressions {
|
if check_too_many_expressions {
|
||||||
if let Some(starred_index) = starred_index {
|
if let Some(starred_index) = starred_index {
|
||||||
if starred_index >= 1 << 8 || elts.len() - starred_index > 1 << 24 {
|
if starred_index >= 1 << 8 || elts.len() - starred_index > 1 << 24 {
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
(*a, *b) = (1, 2)
|
||||||
|
[*a, *b] = (1, 2)
|
||||||
|
(*a, *b, c) = (1, 2, 3)
|
||||||
|
[*a, *b, c] = (1, 2, 3)
|
||||||
|
(*a, *b, (*c, *d)) = (1, 2)
|
|
@ -0,0 +1,2 @@
|
||||||
|
(*a, b) = (1, 2)
|
||||||
|
(*_, normed), *_ = [(1,), 2]
|
|
@ -389,6 +389,40 @@ impl SemanticSyntaxChecker {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn multiple_star_expression<Ctx: SemanticSyntaxContext>(
|
||||||
|
ctx: &Ctx,
|
||||||
|
expr_ctx: ExprContext,
|
||||||
|
elts: &[Expr],
|
||||||
|
range: TextRange,
|
||||||
|
) {
|
||||||
|
if expr_ctx.is_store() {
|
||||||
|
let mut has_starred = false;
|
||||||
|
for elt in elts {
|
||||||
|
if elt.is_starred_expr() {
|
||||||
|
if has_starred {
|
||||||
|
// test_err multiple_starred_assignment_target
|
||||||
|
// (*a, *b) = (1, 2)
|
||||||
|
// [*a, *b] = (1, 2)
|
||||||
|
// (*a, *b, c) = (1, 2, 3)
|
||||||
|
// [*a, *b, c] = (1, 2, 3)
|
||||||
|
// (*a, *b, (*c, *d)) = (1, 2)
|
||||||
|
|
||||||
|
// test_ok multiple_starred_assignment_target
|
||||||
|
// (*a, b) = (1, 2)
|
||||||
|
// (*_, normed), *_ = [(1,), 2]
|
||||||
|
Self::add_error(
|
||||||
|
ctx,
|
||||||
|
SemanticSyntaxErrorKind::MultipleStarredExpressions,
|
||||||
|
range,
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
has_starred = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Check for [`SemanticSyntaxErrorKind::WriteToDebug`] in `stmt`.
|
/// Check for [`SemanticSyntaxErrorKind::WriteToDebug`] in `stmt`.
|
||||||
fn debug_shadowing<Ctx: SemanticSyntaxContext>(stmt: &ast::Stmt, ctx: &Ctx) {
|
fn debug_shadowing<Ctx: SemanticSyntaxContext>(stmt: &ast::Stmt, ctx: &Ctx) {
|
||||||
match stmt {
|
match stmt {
|
||||||
|
@ -754,6 +788,20 @@ impl SemanticSyntaxChecker {
|
||||||
Self::yield_outside_function(ctx, expr, YieldOutsideFunctionKind::Await);
|
Self::yield_outside_function(ctx, expr, YieldOutsideFunctionKind::Await);
|
||||||
Self::await_outside_async_function(ctx, expr, AwaitOutsideAsyncFunctionKind::Await);
|
Self::await_outside_async_function(ctx, expr, AwaitOutsideAsyncFunctionKind::Await);
|
||||||
}
|
}
|
||||||
|
Expr::Tuple(ast::ExprTuple {
|
||||||
|
elts,
|
||||||
|
ctx: expr_ctx,
|
||||||
|
range,
|
||||||
|
..
|
||||||
|
})
|
||||||
|
| Expr::List(ast::ExprList {
|
||||||
|
elts,
|
||||||
|
ctx: expr_ctx,
|
||||||
|
range,
|
||||||
|
..
|
||||||
|
}) => {
|
||||||
|
Self::multiple_star_expression(ctx, *expr_ctx, elts, *range);
|
||||||
|
}
|
||||||
Expr::Lambda(ast::ExprLambda {
|
Expr::Lambda(ast::ExprLambda {
|
||||||
parameters: Some(parameters),
|
parameters: Some(parameters),
|
||||||
..
|
..
|
||||||
|
@ -1035,6 +1083,9 @@ impl Display for SemanticSyntaxError {
|
||||||
SemanticSyntaxErrorKind::NonModuleImportStar(name) => {
|
SemanticSyntaxErrorKind::NonModuleImportStar(name) => {
|
||||||
write!(f, "`from {name} import *` only allowed at module level")
|
write!(f, "`from {name} import *` only allowed at module level")
|
||||||
}
|
}
|
||||||
|
SemanticSyntaxErrorKind::MultipleStarredExpressions => {
|
||||||
|
write!(f, "Two starred expressions in assignment")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1398,6 +1449,13 @@ pub enum SemanticSyntaxErrorKind {
|
||||||
|
|
||||||
/// Represents the use of `from <module> import *` outside module scope.
|
/// Represents the use of `from <module> import *` outside module scope.
|
||||||
NonModuleImportStar(String),
|
NonModuleImportStar(String),
|
||||||
|
|
||||||
|
/// Represents the use of more than one starred expression in an assignment.
|
||||||
|
///
|
||||||
|
/// Python only allows a single starred target when unpacking values on the
|
||||||
|
/// left-hand side of an assignment. Using multiple starred expressions makes
|
||||||
|
/// the statement invalid and results in a `SyntaxError`.
|
||||||
|
MultipleStarredExpressions,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, get_size2::GetSize)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, get_size2::GetSize)]
|
||||||
|
|
|
@ -0,0 +1,520 @@
|
||||||
|
---
|
||||||
|
source: crates/ruff_python_parser/tests/fixtures.rs
|
||||||
|
input_file: crates/ruff_python_parser/resources/inline/err/multiple_starred_assignment_target.py
|
||||||
|
---
|
||||||
|
## AST
|
||||||
|
|
||||||
|
```
|
||||||
|
Module(
|
||||||
|
ModModule {
|
||||||
|
node_index: NodeIndex(None),
|
||||||
|
range: 0..112,
|
||||||
|
body: [
|
||||||
|
Assign(
|
||||||
|
StmtAssign {
|
||||||
|
node_index: NodeIndex(None),
|
||||||
|
range: 0..17,
|
||||||
|
targets: [
|
||||||
|
Tuple(
|
||||||
|
ExprTuple {
|
||||||
|
node_index: NodeIndex(None),
|
||||||
|
range: 0..8,
|
||||||
|
elts: [
|
||||||
|
Starred(
|
||||||
|
ExprStarred {
|
||||||
|
node_index: NodeIndex(None),
|
||||||
|
range: 1..3,
|
||||||
|
value: Name(
|
||||||
|
ExprName {
|
||||||
|
node_index: NodeIndex(None),
|
||||||
|
range: 2..3,
|
||||||
|
id: Name("a"),
|
||||||
|
ctx: Store,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
ctx: Store,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
Starred(
|
||||||
|
ExprStarred {
|
||||||
|
node_index: NodeIndex(None),
|
||||||
|
range: 5..7,
|
||||||
|
value: Name(
|
||||||
|
ExprName {
|
||||||
|
node_index: NodeIndex(None),
|
||||||
|
range: 6..7,
|
||||||
|
id: Name("b"),
|
||||||
|
ctx: Store,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
ctx: Store,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
ctx: Store,
|
||||||
|
parenthesized: true,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
value: Tuple(
|
||||||
|
ExprTuple {
|
||||||
|
node_index: NodeIndex(None),
|
||||||
|
range: 11..17,
|
||||||
|
elts: [
|
||||||
|
NumberLiteral(
|
||||||
|
ExprNumberLiteral {
|
||||||
|
node_index: NodeIndex(None),
|
||||||
|
range: 12..13,
|
||||||
|
value: Int(
|
||||||
|
1,
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
NumberLiteral(
|
||||||
|
ExprNumberLiteral {
|
||||||
|
node_index: NodeIndex(None),
|
||||||
|
range: 15..16,
|
||||||
|
value: Int(
|
||||||
|
2,
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
ctx: Load,
|
||||||
|
parenthesized: true,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
Assign(
|
||||||
|
StmtAssign {
|
||||||
|
node_index: NodeIndex(None),
|
||||||
|
range: 18..35,
|
||||||
|
targets: [
|
||||||
|
List(
|
||||||
|
ExprList {
|
||||||
|
node_index: NodeIndex(None),
|
||||||
|
range: 18..26,
|
||||||
|
elts: [
|
||||||
|
Starred(
|
||||||
|
ExprStarred {
|
||||||
|
node_index: NodeIndex(None),
|
||||||
|
range: 19..21,
|
||||||
|
value: Name(
|
||||||
|
ExprName {
|
||||||
|
node_index: NodeIndex(None),
|
||||||
|
range: 20..21,
|
||||||
|
id: Name("a"),
|
||||||
|
ctx: Store,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
ctx: Store,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
Starred(
|
||||||
|
ExprStarred {
|
||||||
|
node_index: NodeIndex(None),
|
||||||
|
range: 23..25,
|
||||||
|
value: Name(
|
||||||
|
ExprName {
|
||||||
|
node_index: NodeIndex(None),
|
||||||
|
range: 24..25,
|
||||||
|
id: Name("b"),
|
||||||
|
ctx: Store,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
ctx: Store,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
ctx: Store,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
value: Tuple(
|
||||||
|
ExprTuple {
|
||||||
|
node_index: NodeIndex(None),
|
||||||
|
range: 29..35,
|
||||||
|
elts: [
|
||||||
|
NumberLiteral(
|
||||||
|
ExprNumberLiteral {
|
||||||
|
node_index: NodeIndex(None),
|
||||||
|
range: 30..31,
|
||||||
|
value: Int(
|
||||||
|
1,
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
NumberLiteral(
|
||||||
|
ExprNumberLiteral {
|
||||||
|
node_index: NodeIndex(None),
|
||||||
|
range: 33..34,
|
||||||
|
value: Int(
|
||||||
|
2,
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
ctx: Load,
|
||||||
|
parenthesized: true,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
Assign(
|
||||||
|
StmtAssign {
|
||||||
|
node_index: NodeIndex(None),
|
||||||
|
range: 36..59,
|
||||||
|
targets: [
|
||||||
|
Tuple(
|
||||||
|
ExprTuple {
|
||||||
|
node_index: NodeIndex(None),
|
||||||
|
range: 36..47,
|
||||||
|
elts: [
|
||||||
|
Starred(
|
||||||
|
ExprStarred {
|
||||||
|
node_index: NodeIndex(None),
|
||||||
|
range: 37..39,
|
||||||
|
value: Name(
|
||||||
|
ExprName {
|
||||||
|
node_index: NodeIndex(None),
|
||||||
|
range: 38..39,
|
||||||
|
id: Name("a"),
|
||||||
|
ctx: Store,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
ctx: Store,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
Starred(
|
||||||
|
ExprStarred {
|
||||||
|
node_index: NodeIndex(None),
|
||||||
|
range: 41..43,
|
||||||
|
value: Name(
|
||||||
|
ExprName {
|
||||||
|
node_index: NodeIndex(None),
|
||||||
|
range: 42..43,
|
||||||
|
id: Name("b"),
|
||||||
|
ctx: Store,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
ctx: Store,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
Name(
|
||||||
|
ExprName {
|
||||||
|
node_index: NodeIndex(None),
|
||||||
|
range: 45..46,
|
||||||
|
id: Name("c"),
|
||||||
|
ctx: Store,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
ctx: Store,
|
||||||
|
parenthesized: true,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
value: Tuple(
|
||||||
|
ExprTuple {
|
||||||
|
node_index: NodeIndex(None),
|
||||||
|
range: 50..59,
|
||||||
|
elts: [
|
||||||
|
NumberLiteral(
|
||||||
|
ExprNumberLiteral {
|
||||||
|
node_index: NodeIndex(None),
|
||||||
|
range: 51..52,
|
||||||
|
value: Int(
|
||||||
|
1,
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
NumberLiteral(
|
||||||
|
ExprNumberLiteral {
|
||||||
|
node_index: NodeIndex(None),
|
||||||
|
range: 54..55,
|
||||||
|
value: Int(
|
||||||
|
2,
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
NumberLiteral(
|
||||||
|
ExprNumberLiteral {
|
||||||
|
node_index: NodeIndex(None),
|
||||||
|
range: 57..58,
|
||||||
|
value: Int(
|
||||||
|
3,
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
ctx: Load,
|
||||||
|
parenthesized: true,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
Assign(
|
||||||
|
StmtAssign {
|
||||||
|
node_index: NodeIndex(None),
|
||||||
|
range: 60..83,
|
||||||
|
targets: [
|
||||||
|
List(
|
||||||
|
ExprList {
|
||||||
|
node_index: NodeIndex(None),
|
||||||
|
range: 60..71,
|
||||||
|
elts: [
|
||||||
|
Starred(
|
||||||
|
ExprStarred {
|
||||||
|
node_index: NodeIndex(None),
|
||||||
|
range: 61..63,
|
||||||
|
value: Name(
|
||||||
|
ExprName {
|
||||||
|
node_index: NodeIndex(None),
|
||||||
|
range: 62..63,
|
||||||
|
id: Name("a"),
|
||||||
|
ctx: Store,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
ctx: Store,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
Starred(
|
||||||
|
ExprStarred {
|
||||||
|
node_index: NodeIndex(None),
|
||||||
|
range: 65..67,
|
||||||
|
value: Name(
|
||||||
|
ExprName {
|
||||||
|
node_index: NodeIndex(None),
|
||||||
|
range: 66..67,
|
||||||
|
id: Name("b"),
|
||||||
|
ctx: Store,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
ctx: Store,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
Name(
|
||||||
|
ExprName {
|
||||||
|
node_index: NodeIndex(None),
|
||||||
|
range: 69..70,
|
||||||
|
id: Name("c"),
|
||||||
|
ctx: Store,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
ctx: Store,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
value: Tuple(
|
||||||
|
ExprTuple {
|
||||||
|
node_index: NodeIndex(None),
|
||||||
|
range: 74..83,
|
||||||
|
elts: [
|
||||||
|
NumberLiteral(
|
||||||
|
ExprNumberLiteral {
|
||||||
|
node_index: NodeIndex(None),
|
||||||
|
range: 75..76,
|
||||||
|
value: Int(
|
||||||
|
1,
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
NumberLiteral(
|
||||||
|
ExprNumberLiteral {
|
||||||
|
node_index: NodeIndex(None),
|
||||||
|
range: 78..79,
|
||||||
|
value: Int(
|
||||||
|
2,
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
NumberLiteral(
|
||||||
|
ExprNumberLiteral {
|
||||||
|
node_index: NodeIndex(None),
|
||||||
|
range: 81..82,
|
||||||
|
value: Int(
|
||||||
|
3,
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
ctx: Load,
|
||||||
|
parenthesized: true,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
Assign(
|
||||||
|
StmtAssign {
|
||||||
|
node_index: NodeIndex(None),
|
||||||
|
range: 84..111,
|
||||||
|
targets: [
|
||||||
|
Tuple(
|
||||||
|
ExprTuple {
|
||||||
|
node_index: NodeIndex(None),
|
||||||
|
range: 84..102,
|
||||||
|
elts: [
|
||||||
|
Starred(
|
||||||
|
ExprStarred {
|
||||||
|
node_index: NodeIndex(None),
|
||||||
|
range: 85..87,
|
||||||
|
value: Name(
|
||||||
|
ExprName {
|
||||||
|
node_index: NodeIndex(None),
|
||||||
|
range: 86..87,
|
||||||
|
id: Name("a"),
|
||||||
|
ctx: Store,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
ctx: Store,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
Starred(
|
||||||
|
ExprStarred {
|
||||||
|
node_index: NodeIndex(None),
|
||||||
|
range: 89..91,
|
||||||
|
value: Name(
|
||||||
|
ExprName {
|
||||||
|
node_index: NodeIndex(None),
|
||||||
|
range: 90..91,
|
||||||
|
id: Name("b"),
|
||||||
|
ctx: Store,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
ctx: Store,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
Tuple(
|
||||||
|
ExprTuple {
|
||||||
|
node_index: NodeIndex(None),
|
||||||
|
range: 93..101,
|
||||||
|
elts: [
|
||||||
|
Starred(
|
||||||
|
ExprStarred {
|
||||||
|
node_index: NodeIndex(None),
|
||||||
|
range: 94..96,
|
||||||
|
value: Name(
|
||||||
|
ExprName {
|
||||||
|
node_index: NodeIndex(None),
|
||||||
|
range: 95..96,
|
||||||
|
id: Name("c"),
|
||||||
|
ctx: Store,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
ctx: Store,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
Starred(
|
||||||
|
ExprStarred {
|
||||||
|
node_index: NodeIndex(None),
|
||||||
|
range: 98..100,
|
||||||
|
value: Name(
|
||||||
|
ExprName {
|
||||||
|
node_index: NodeIndex(None),
|
||||||
|
range: 99..100,
|
||||||
|
id: Name("d"),
|
||||||
|
ctx: Store,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
ctx: Store,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
ctx: Store,
|
||||||
|
parenthesized: true,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
ctx: Store,
|
||||||
|
parenthesized: true,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
value: Tuple(
|
||||||
|
ExprTuple {
|
||||||
|
node_index: NodeIndex(None),
|
||||||
|
range: 105..111,
|
||||||
|
elts: [
|
||||||
|
NumberLiteral(
|
||||||
|
ExprNumberLiteral {
|
||||||
|
node_index: NodeIndex(None),
|
||||||
|
range: 106..107,
|
||||||
|
value: Int(
|
||||||
|
1,
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
NumberLiteral(
|
||||||
|
ExprNumberLiteral {
|
||||||
|
node_index: NodeIndex(None),
|
||||||
|
range: 109..110,
|
||||||
|
value: Int(
|
||||||
|
2,
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
ctx: Load,
|
||||||
|
parenthesized: true,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
)
|
||||||
|
```
|
||||||
|
## Semantic Syntax Errors
|
||||||
|
|
||||||
|
|
|
||||||
|
1 | (*a, *b) = (1, 2)
|
||||||
|
| ^^^^^^^^ Syntax Error: Two starred expressions in assignment
|
||||||
|
2 | [*a, *b] = (1, 2)
|
||||||
|
3 | (*a, *b, c) = (1, 2, 3)
|
||||||
|
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
1 | (*a, *b) = (1, 2)
|
||||||
|
2 | [*a, *b] = (1, 2)
|
||||||
|
| ^^^^^^^^ Syntax Error: Two starred expressions in assignment
|
||||||
|
3 | (*a, *b, c) = (1, 2, 3)
|
||||||
|
4 | [*a, *b, c] = (1, 2, 3)
|
||||||
|
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
1 | (*a, *b) = (1, 2)
|
||||||
|
2 | [*a, *b] = (1, 2)
|
||||||
|
3 | (*a, *b, c) = (1, 2, 3)
|
||||||
|
| ^^^^^^^^^^^ Syntax Error: Two starred expressions in assignment
|
||||||
|
4 | [*a, *b, c] = (1, 2, 3)
|
||||||
|
5 | (*a, *b, (*c, *d)) = (1, 2)
|
||||||
|
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
2 | [*a, *b] = (1, 2)
|
||||||
|
3 | (*a, *b, c) = (1, 2, 3)
|
||||||
|
4 | [*a, *b, c] = (1, 2, 3)
|
||||||
|
| ^^^^^^^^^^^ Syntax Error: Two starred expressions in assignment
|
||||||
|
5 | (*a, *b, (*c, *d)) = (1, 2)
|
||||||
|
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
3 | (*a, *b, c) = (1, 2, 3)
|
||||||
|
4 | [*a, *b, c] = (1, 2, 3)
|
||||||
|
5 | (*a, *b, (*c, *d)) = (1, 2)
|
||||||
|
| ^^^^^^^^^^^^^^^^^^ Syntax Error: Two starred expressions in assignment
|
||||||
|
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
3 | (*a, *b, c) = (1, 2, 3)
|
||||||
|
4 | [*a, *b, c] = (1, 2, 3)
|
||||||
|
5 | (*a, *b, (*c, *d)) = (1, 2)
|
||||||
|
| ^^^^^^^^ Syntax Error: Two starred expressions in assignment
|
||||||
|
|
|
|
@ -0,0 +1,188 @@
|
||||||
|
---
|
||||||
|
source: crates/ruff_python_parser/tests/fixtures.rs
|
||||||
|
input_file: crates/ruff_python_parser/resources/inline/ok/multiple_starred_assignment_target.py
|
||||||
|
---
|
||||||
|
## AST
|
||||||
|
|
||||||
|
```
|
||||||
|
Module(
|
||||||
|
ModModule {
|
||||||
|
node_index: NodeIndex(None),
|
||||||
|
range: 0..46,
|
||||||
|
body: [
|
||||||
|
Assign(
|
||||||
|
StmtAssign {
|
||||||
|
node_index: NodeIndex(None),
|
||||||
|
range: 0..16,
|
||||||
|
targets: [
|
||||||
|
Tuple(
|
||||||
|
ExprTuple {
|
||||||
|
node_index: NodeIndex(None),
|
||||||
|
range: 0..7,
|
||||||
|
elts: [
|
||||||
|
Starred(
|
||||||
|
ExprStarred {
|
||||||
|
node_index: NodeIndex(None),
|
||||||
|
range: 1..3,
|
||||||
|
value: Name(
|
||||||
|
ExprName {
|
||||||
|
node_index: NodeIndex(None),
|
||||||
|
range: 2..3,
|
||||||
|
id: Name("a"),
|
||||||
|
ctx: Store,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
ctx: Store,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
Name(
|
||||||
|
ExprName {
|
||||||
|
node_index: NodeIndex(None),
|
||||||
|
range: 5..6,
|
||||||
|
id: Name("b"),
|
||||||
|
ctx: Store,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
ctx: Store,
|
||||||
|
parenthesized: true,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
value: Tuple(
|
||||||
|
ExprTuple {
|
||||||
|
node_index: NodeIndex(None),
|
||||||
|
range: 10..16,
|
||||||
|
elts: [
|
||||||
|
NumberLiteral(
|
||||||
|
ExprNumberLiteral {
|
||||||
|
node_index: NodeIndex(None),
|
||||||
|
range: 11..12,
|
||||||
|
value: Int(
|
||||||
|
1,
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
NumberLiteral(
|
||||||
|
ExprNumberLiteral {
|
||||||
|
node_index: NodeIndex(None),
|
||||||
|
range: 14..15,
|
||||||
|
value: Int(
|
||||||
|
2,
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
ctx: Load,
|
||||||
|
parenthesized: true,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
Assign(
|
||||||
|
StmtAssign {
|
||||||
|
node_index: NodeIndex(None),
|
||||||
|
range: 17..45,
|
||||||
|
targets: [
|
||||||
|
Tuple(
|
||||||
|
ExprTuple {
|
||||||
|
node_index: NodeIndex(None),
|
||||||
|
range: 17..33,
|
||||||
|
elts: [
|
||||||
|
Tuple(
|
||||||
|
ExprTuple {
|
||||||
|
node_index: NodeIndex(None),
|
||||||
|
range: 17..29,
|
||||||
|
elts: [
|
||||||
|
Starred(
|
||||||
|
ExprStarred {
|
||||||
|
node_index: NodeIndex(None),
|
||||||
|
range: 18..20,
|
||||||
|
value: Name(
|
||||||
|
ExprName {
|
||||||
|
node_index: NodeIndex(None),
|
||||||
|
range: 19..20,
|
||||||
|
id: Name("_"),
|
||||||
|
ctx: Store,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
ctx: Store,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
Name(
|
||||||
|
ExprName {
|
||||||
|
node_index: NodeIndex(None),
|
||||||
|
range: 22..28,
|
||||||
|
id: Name("normed"),
|
||||||
|
ctx: Store,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
ctx: Store,
|
||||||
|
parenthesized: true,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
Starred(
|
||||||
|
ExprStarred {
|
||||||
|
node_index: NodeIndex(None),
|
||||||
|
range: 31..33,
|
||||||
|
value: Name(
|
||||||
|
ExprName {
|
||||||
|
node_index: NodeIndex(None),
|
||||||
|
range: 32..33,
|
||||||
|
id: Name("_"),
|
||||||
|
ctx: Store,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
ctx: Store,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
ctx: Store,
|
||||||
|
parenthesized: false,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
value: List(
|
||||||
|
ExprList {
|
||||||
|
node_index: NodeIndex(None),
|
||||||
|
range: 36..45,
|
||||||
|
elts: [
|
||||||
|
Tuple(
|
||||||
|
ExprTuple {
|
||||||
|
node_index: NodeIndex(None),
|
||||||
|
range: 37..41,
|
||||||
|
elts: [
|
||||||
|
NumberLiteral(
|
||||||
|
ExprNumberLiteral {
|
||||||
|
node_index: NodeIndex(None),
|
||||||
|
range: 38..39,
|
||||||
|
value: Int(
|
||||||
|
1,
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
ctx: Load,
|
||||||
|
parenthesized: true,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
NumberLiteral(
|
||||||
|
ExprNumberLiteral {
|
||||||
|
node_index: NodeIndex(None),
|
||||||
|
range: 43..44,
|
||||||
|
value: Int(
|
||||||
|
2,
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
ctx: Load,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
)
|
||||||
|
```
|
Loading…
Add table
Add a link
Reference in a new issue