diff --git a/crates/ruff_python_parser/resources/inline/ok/parenthesized_star_index_py310.py b/crates/ruff_python_parser/resources/inline/ok/parenthesized_star_index_py310.py new file mode 100644 index 0000000000..9b31dd9274 --- /dev/null +++ b/crates/ruff_python_parser/resources/inline/ok/parenthesized_star_index_py310.py @@ -0,0 +1,2 @@ +# parse_options: {"target-version": "3.10"} +out[(*(slice(None) for _ in range(2)), *ind)] = 1 diff --git a/crates/ruff_python_parser/src/parser/expression.rs b/crates/ruff_python_parser/src/parser/expression.rs index 4e1fd6dff1..bbb26751a6 100644 --- a/crates/ruff_python_parser/src/parser/expression.rs +++ b/crates/ruff_python_parser/src/parser/expression.rs @@ -875,7 +875,16 @@ impl<'src> Parser<'src> { // test_err star_slices // array[*start:*end] - if let Expr::Tuple(ast::ExprTuple { elts, .. }) = &slice { + + // test_ok parenthesized_star_index_py310 + // # parse_options: {"target-version": "3.10"} + // out[(*(slice(None) for _ in range(2)), *ind)] = 1 + if let Expr::Tuple(ast::ExprTuple { + elts, + parenthesized: false, + .. + }) = &slice + { for elt in elts.iter().filter(|elt| elt.is_starred_expr()) { self.add_unsupported_syntax_error( UnsupportedSyntaxErrorKind::StarExpressionInIndex, diff --git a/crates/ruff_python_parser/tests/snapshots/valid_syntax@parenthesized_star_index_py310.py.snap b/crates/ruff_python_parser/tests/snapshots/valid_syntax@parenthesized_star_index_py310.py.snap new file mode 100644 index 0000000000..10df276256 --- /dev/null +++ b/crates/ruff_python_parser/tests/snapshots/valid_syntax@parenthesized_star_index_py310.py.snap @@ -0,0 +1,141 @@ +--- +source: crates/ruff_python_parser/tests/fixtures.rs +input_file: crates/ruff_python_parser/resources/inline/ok/parenthesized_star_index_py310.py +snapshot_kind: text +--- +## AST + +``` +Module( + ModModule { + range: 0..94, + body: [ + Assign( + StmtAssign { + range: 44..93, + targets: [ + Subscript( + ExprSubscript { + range: 44..89, + value: Name( + ExprName { + range: 44..47, + id: Name("out"), + ctx: Load, + }, + ), + slice: Tuple( + ExprTuple { + range: 48..88, + elts: [ + Starred( + ExprStarred { + range: 49..81, + value: Generator( + ExprGenerator { + range: 50..81, + elt: Call( + ExprCall { + range: 51..62, + func: Name( + ExprName { + range: 51..56, + id: Name("slice"), + ctx: Load, + }, + ), + arguments: Arguments { + range: 56..62, + args: [ + NoneLiteral( + ExprNoneLiteral { + range: 57..61, + }, + ), + ], + keywords: [], + }, + }, + ), + generators: [ + Comprehension { + range: 63..80, + target: Name( + ExprName { + range: 67..68, + id: Name("_"), + ctx: Store, + }, + ), + iter: Call( + ExprCall { + range: 72..80, + func: Name( + ExprName { + range: 72..77, + id: Name("range"), + ctx: Load, + }, + ), + arguments: Arguments { + range: 77..80, + args: [ + NumberLiteral( + ExprNumberLiteral { + range: 78..79, + value: Int( + 2, + ), + }, + ), + ], + keywords: [], + }, + }, + ), + ifs: [], + is_async: false, + }, + ], + parenthesized: true, + }, + ), + ctx: Load, + }, + ), + Starred( + ExprStarred { + range: 83..87, + value: Name( + ExprName { + range: 84..87, + id: Name("ind"), + ctx: Load, + }, + ), + ctx: Load, + }, + ), + ], + ctx: Load, + parenthesized: true, + }, + ), + ctx: Store, + }, + ), + ], + value: NumberLiteral( + ExprNumberLiteral { + range: 92..93, + value: Int( + 1, + ), + }, + ), + }, + ), + ], + }, +) +```