Skip to content

Commit 5f88756

Browse files
authored
Disallow starred expressions as values of starred expressions (#24280)
Part of #19077
1 parent 5c59f8a commit 5f88756

3 files changed

Lines changed: 145 additions & 3 deletions

File tree

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
print(*
2+
*[])
3+
print(* *[])

crates/ruff_python_parser/src/parser/expression.rs

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2545,9 +2545,14 @@ impl<'src> Parser<'src> {
25452545
self.bump(TokenKind::Star);
25462546

25472547
let parsed_expr = match context.starred_expression_precedence() {
2548-
StarredExpressionPrecedence::Conditional => {
2549-
self.parse_conditional_expression_or_higher_impl(context)
2550-
}
2548+
StarredExpressionPrecedence::Conditional => self
2549+
.parse_conditional_expression_or_higher_impl(
2550+
// test_err starred_starred_expression
2551+
// print(*
2552+
// *[])
2553+
// print(* *[])
2554+
context.disallow_starred_expressions(),
2555+
),
25512556
StarredExpressionPrecedence::BitwiseOr => {
25522557
self.parse_expression_with_bitwise_or_precedence()
25532558
}
@@ -2999,6 +3004,11 @@ impl ExpressionContext {
29993004
ExpressionContext::starred_bitwise_or().with_yield_expression_allowed()
30003005
}
30013006

3007+
pub(super) fn disallow_starred_expressions(self) -> Self {
3008+
let flags = self.0 & !ExpressionContextFlags::ALLOW_STARRED_EXPRESSION;
3009+
ExpressionContext(flags)
3010+
}
3011+
30023012
/// Returns a new [`ExpressionContext`] which allows starred expression with the given
30033013
/// precedence.
30043014
fn with_starred_expression_allowed(self, precedence: StarredExpressionPrecedence) -> Self {
Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
---
2+
source: crates/ruff_python_parser/tests/fixtures.rs
3+
---
4+
## AST
5+
6+
```
7+
Module(
8+
ModModule {
9+
node_index: NodeIndex(None),
10+
range: 0..26,
11+
body: [
12+
Expr(
13+
StmtExpr {
14+
node_index: NodeIndex(None),
15+
range: 0..12,
16+
value: Call(
17+
ExprCall {
18+
node_index: NodeIndex(None),
19+
range: 0..12,
20+
func: Name(
21+
ExprName {
22+
node_index: NodeIndex(None),
23+
range: 0..5,
24+
id: Name("print"),
25+
ctx: Load,
26+
},
27+
),
28+
arguments: Arguments {
29+
range: 5..12,
30+
node_index: NodeIndex(None),
31+
args: [
32+
Starred(
33+
ExprStarred {
34+
node_index: NodeIndex(None),
35+
range: 6..11,
36+
value: Starred(
37+
ExprStarred {
38+
node_index: NodeIndex(None),
39+
range: 8..11,
40+
value: List(
41+
ExprList {
42+
node_index: NodeIndex(None),
43+
range: 9..11,
44+
elts: [],
45+
ctx: Load,
46+
},
47+
),
48+
ctx: Load,
49+
},
50+
),
51+
ctx: Load,
52+
},
53+
),
54+
],
55+
keywords: [],
56+
},
57+
},
58+
),
59+
},
60+
),
61+
Expr(
62+
StmtExpr {
63+
node_index: NodeIndex(None),
64+
range: 13..25,
65+
value: Call(
66+
ExprCall {
67+
node_index: NodeIndex(None),
68+
range: 13..25,
69+
func: Name(
70+
ExprName {
71+
node_index: NodeIndex(None),
72+
range: 13..18,
73+
id: Name("print"),
74+
ctx: Load,
75+
},
76+
),
77+
arguments: Arguments {
78+
range: 18..25,
79+
node_index: NodeIndex(None),
80+
args: [
81+
Starred(
82+
ExprStarred {
83+
node_index: NodeIndex(None),
84+
range: 19..24,
85+
value: Starred(
86+
ExprStarred {
87+
node_index: NodeIndex(None),
88+
range: 21..24,
89+
value: List(
90+
ExprList {
91+
node_index: NodeIndex(None),
92+
range: 22..24,
93+
elts: [],
94+
ctx: Load,
95+
},
96+
),
97+
ctx: Load,
98+
},
99+
),
100+
ctx: Load,
101+
},
102+
),
103+
],
104+
keywords: [],
105+
},
106+
},
107+
),
108+
},
109+
),
110+
],
111+
},
112+
)
113+
```
114+
## Errors
115+
116+
|
117+
1 | print(*
118+
2 | *[])
119+
| ^^^ Syntax Error: Starred expression cannot be used here
120+
3 | print(* *[])
121+
|
122+
123+
124+
|
125+
1 | print(*
126+
2 | *[])
127+
3 | print(* *[])
128+
| ^^^ Syntax Error: Starred expression cannot be used here
129+
|

0 commit comments

Comments
 (0)