Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
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,3 @@
print(*
*[])
print(* *[])
16 changes: 13 additions & 3 deletions crates/ruff_python_parser/src/parser/expression.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2545,9 +2545,14 @@ impl<'src> Parser<'src> {
self.bump(TokenKind::Star);

let parsed_expr = match context.starred_expression_precedence() {
StarredExpressionPrecedence::Conditional => {
self.parse_conditional_expression_or_higher_impl(context)
}
StarredExpressionPrecedence::Conditional => self
.parse_conditional_expression_or_higher_impl(
// test_err starred_starred_expression
// print(*
// *[])
// print(* *[])
context.disallow_starred_expressions(),
),
StarredExpressionPrecedence::BitwiseOr => {
Comment on lines 2547 to 2556
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I initially thought this might not be the correct place but then I realize that this is actually correct given that if we're parsing an expression followed by the * token, then that expression cannot itself be a starred expression unless it's a keyword-variadic argument which is actually a different token (**).

I think we should add this example as well:

print(* *[])

For posterity, I thought the issue must be in parse_arguments instead. The lexer emits [..., Star, Star, ...] for the above code and [..., Star, NonLogicalNewline, Star, ...] for the one in the test. So, I thought we'd need to special case this order of two consecutive Star tokens that could contain a NonLogicalNewline token in between and check whether they're actually consecutive or not.

self.parse_expression_with_bitwise_or_precedence()
}
Expand Down Expand Up @@ -2999,6 +3004,11 @@ impl ExpressionContext {
ExpressionContext::starred_bitwise_or().with_yield_expression_allowed()
}

pub(super) fn disallow_starred_expressions(self) -> Self {
let flags = self.0 & !ExpressionContextFlags::ALLOW_STARRED_EXPRESSION;
ExpressionContext(flags)
}

/// Returns a new [`ExpressionContext`] which allows starred expression with the given
/// precedence.
fn with_starred_expression_allowed(self, precedence: StarredExpressionPrecedence) -> Self {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
---
source: crates/ruff_python_parser/tests/fixtures.rs
---
## AST

```
Module(
ModModule {
node_index: NodeIndex(None),
range: 0..26,
body: [
Expr(
StmtExpr {
node_index: NodeIndex(None),
range: 0..12,
value: Call(
ExprCall {
node_index: NodeIndex(None),
range: 0..12,
func: Name(
ExprName {
node_index: NodeIndex(None),
range: 0..5,
id: Name("print"),
ctx: Load,
},
),
arguments: Arguments {
range: 5..12,
node_index: NodeIndex(None),
args: [
Starred(
ExprStarred {
node_index: NodeIndex(None),
range: 6..11,
value: Starred(
ExprStarred {
node_index: NodeIndex(None),
range: 8..11,
value: List(
ExprList {
node_index: NodeIndex(None),
range: 9..11,
elts: [],
ctx: Load,
},
),
ctx: Load,
},
),
ctx: Load,
},
),
],
keywords: [],
},
},
),
},
),
Expr(
StmtExpr {
node_index: NodeIndex(None),
range: 13..25,
value: Call(
ExprCall {
node_index: NodeIndex(None),
range: 13..25,
func: Name(
ExprName {
node_index: NodeIndex(None),
range: 13..18,
id: Name("print"),
ctx: Load,
},
),
arguments: Arguments {
range: 18..25,
node_index: NodeIndex(None),
args: [
Starred(
ExprStarred {
node_index: NodeIndex(None),
range: 19..24,
value: Starred(
ExprStarred {
node_index: NodeIndex(None),
range: 21..24,
value: List(
ExprList {
node_index: NodeIndex(None),
range: 22..24,
elts: [],
ctx: Load,
},
),
ctx: Load,
},
),
ctx: Load,
},
),
],
keywords: [],
},
},
),
},
),
],
},
)
```
## Errors

|
1 | print(*
2 | *[])
| ^^^ Syntax Error: Starred expression cannot be used here
3 | print(* *[])
|


|
1 | print(*
2 | *[])
3 | print(* *[])
| ^^^ Syntax Error: Starred expression cannot be used here
|
Loading