mirror of
https://github.com/astral-sh/ruff.git
synced 2025-08-30 23:27:38 +00:00
Add ExpressionContext
for expression parsing (#11055)
## Summary This PR adds a new `ExpressionContext` struct which is used in expression parsing. This solves the following problem: 1. Allowing starred expression with different precedence 2. Allowing yield expression in certain context 3. Remove ambiguity with `in` keyword when parsing a `for ... in` statement For context, (1) was solved by adding `parse_star_expression_list` and `parse_star_expression_or_higher` in #10623, (2) was solved by by adding `parse_yield_expression_or_else` in #10809, and (3) was fixed in #11009. All of the mentioned functions have been removed in favor of the context flags. As mentioned in #11009, an ideal solution would be to implement an expression context which is what this PR implements. This is passed around as function parameter and the call stack is used to automatically reset the context. ### Recovery How should the parser recover if the target expression is invalid when an expression can consume the `in` keyword? 1. Should the `in` keyword be part of the target expression? 2. Or, should the expression parsing stop as soon as `in` keyword is encountered, no matter the expression? For example: ```python for yield x in y: ... # Here, should this be parsed as for (yield x) in (y): ... # Or for (yield x in y): ... # where the `in iter` part is missing ``` Or, for binary expression parsing: ```python for x or y in z: ... # Should this be parsed as for (x or y) in z: ... # Or for (x or y in z): ... # where the `in iter` part is missing ``` This need not be solved now, but is very easy to change. For context this PR does the following: * For binary, comparison, and unary expressions, stop at `in` * For lambda, yield expressions, consume the `in` ## Test Plan 1. Add test cases for the `for ... in` statement and verify the snapshots 2. Make sure the existing test suite pass 3. Run the fuzzer for around 3000 generated source code 4. Run the updated logic on a dozen or so open source repositories (codename "parser-checkouts")
This commit is contained in:
parent
62478c3070
commit
c30735d4a7
22 changed files with 1151 additions and 869 deletions
|
@ -346,24 +346,29 @@ Module(
|
|||
ExprList {
|
||||
range: 187..199,
|
||||
elts: [
|
||||
Starred(
|
||||
ExprStarred {
|
||||
range: 188..190,
|
||||
value: Name(
|
||||
ExprName {
|
||||
range: 189..190,
|
||||
id: "x",
|
||||
ctx: Load,
|
||||
Named(
|
||||
ExprNamed {
|
||||
range: 188..195,
|
||||
target: Starred(
|
||||
ExprStarred {
|
||||
range: 188..190,
|
||||
value: Name(
|
||||
ExprName {
|
||||
range: 189..190,
|
||||
id: "x",
|
||||
ctx: Store,
|
||||
},
|
||||
),
|
||||
ctx: Store,
|
||||
},
|
||||
),
|
||||
ctx: Load,
|
||||
},
|
||||
),
|
||||
NumberLiteral(
|
||||
ExprNumberLiteral {
|
||||
range: 194..195,
|
||||
value: Int(
|
||||
2,
|
||||
value: NumberLiteral(
|
||||
ExprNumberLiteral {
|
||||
range: 194..195,
|
||||
value: Int(
|
||||
2,
|
||||
),
|
||||
},
|
||||
),
|
||||
},
|
||||
),
|
||||
|
@ -458,5 +463,5 @@ Module(
|
|||
8 | [*x if True else y, z]
|
||||
9 | [*lambda x: x, z]
|
||||
10 | [*x := 2, z]
|
||||
| ^^ Syntax Error: Expected ',', found ':='
|
||||
| ^^ Syntax Error: Assignment expression target must be an identifier
|
||||
|
|
||||
|
|
|
@ -84,30 +84,30 @@ Module(
|
|||
),
|
||||
Expr(
|
||||
StmtExpr {
|
||||
range: 81..84,
|
||||
value: Starred(
|
||||
ExprStarred {
|
||||
range: 82..84,
|
||||
value: Name(
|
||||
ExprName {
|
||||
range: 83..84,
|
||||
id: "x",
|
||||
ctx: Load,
|
||||
range: 81..90,
|
||||
value: Named(
|
||||
ExprNamed {
|
||||
range: 82..89,
|
||||
target: Starred(
|
||||
ExprStarred {
|
||||
range: 82..84,
|
||||
value: Name(
|
||||
ExprName {
|
||||
range: 83..84,
|
||||
id: "x",
|
||||
ctx: Store,
|
||||
},
|
||||
),
|
||||
ctx: Store,
|
||||
},
|
||||
),
|
||||
ctx: Load,
|
||||
},
|
||||
),
|
||||
},
|
||||
),
|
||||
Expr(
|
||||
StmtExpr {
|
||||
range: 88..89,
|
||||
value: NumberLiteral(
|
||||
ExprNumberLiteral {
|
||||
range: 88..89,
|
||||
value: Int(
|
||||
1,
|
||||
value: NumberLiteral(
|
||||
ExprNumberLiteral {
|
||||
range: 88..89,
|
||||
value: Int(
|
||||
1,
|
||||
),
|
||||
},
|
||||
),
|
||||
},
|
||||
),
|
||||
|
@ -198,34 +198,7 @@ Module(
|
|||
3 | (x.y := 1)
|
||||
4 | (x[y] := 1)
|
||||
5 | (*x := 1)
|
||||
| ^^ Syntax Error: Starred expression cannot be used here
|
||||
6 | ([x, y] := [1, 2])
|
||||
|
|
||||
|
||||
|
||||
|
|
||||
3 | (x.y := 1)
|
||||
4 | (x[y] := 1)
|
||||
5 | (*x := 1)
|
||||
| ^^ Syntax Error: Expected ')', found ':='
|
||||
6 | ([x, y] := [1, 2])
|
||||
|
|
||||
|
||||
|
||||
|
|
||||
3 | (x.y := 1)
|
||||
4 | (x[y] := 1)
|
||||
5 | (*x := 1)
|
||||
| ^ Syntax Error: Expected a statement
|
||||
6 | ([x, y] := [1, 2])
|
||||
|
|
||||
|
||||
|
||||
|
|
||||
3 | (x.y := 1)
|
||||
4 | (x[y] := 1)
|
||||
5 | (*x := 1)
|
||||
| ^ Syntax Error: Expected a statement
|
||||
| ^^ Syntax Error: Assignment expression target must be an identifier
|
||||
6 | ([x, y] := [1, 2])
|
||||
|
|
||||
|
||||
|
|
|
@ -491,34 +491,34 @@ Module(
|
|||
),
|
||||
Expr(
|
||||
StmtExpr {
|
||||
range: 323..326,
|
||||
value: Starred(
|
||||
ExprStarred {
|
||||
range: 324..326,
|
||||
value: Name(
|
||||
ExprName {
|
||||
range: 325..326,
|
||||
id: "x",
|
||||
ctx: Load,
|
||||
},
|
||||
),
|
||||
ctx: Load,
|
||||
},
|
||||
),
|
||||
},
|
||||
),
|
||||
Expr(
|
||||
StmtExpr {
|
||||
range: 330..343,
|
||||
range: 323..344,
|
||||
value: Tuple(
|
||||
ExprTuple {
|
||||
range: 330..343,
|
||||
range: 323..344,
|
||||
elts: [
|
||||
NumberLiteral(
|
||||
ExprNumberLiteral {
|
||||
range: 330..331,
|
||||
value: Int(
|
||||
2,
|
||||
Named(
|
||||
ExprNamed {
|
||||
range: 324..331,
|
||||
target: Starred(
|
||||
ExprStarred {
|
||||
range: 324..326,
|
||||
value: Name(
|
||||
ExprName {
|
||||
range: 325..326,
|
||||
id: "x",
|
||||
ctx: Store,
|
||||
},
|
||||
),
|
||||
ctx: Store,
|
||||
},
|
||||
),
|
||||
value: NumberLiteral(
|
||||
ExprNumberLiteral {
|
||||
range: 330..331,
|
||||
value: Int(
|
||||
2,
|
||||
),
|
||||
},
|
||||
),
|
||||
},
|
||||
),
|
||||
|
@ -529,30 +529,35 @@ Module(
|
|||
ctx: Load,
|
||||
},
|
||||
),
|
||||
Starred(
|
||||
ExprStarred {
|
||||
range: 336..338,
|
||||
value: Name(
|
||||
ExprName {
|
||||
range: 337..338,
|
||||
id: "x",
|
||||
ctx: Load,
|
||||
Named(
|
||||
ExprNamed {
|
||||
range: 336..343,
|
||||
target: Starred(
|
||||
ExprStarred {
|
||||
range: 336..338,
|
||||
value: Name(
|
||||
ExprName {
|
||||
range: 337..338,
|
||||
id: "x",
|
||||
ctx: Store,
|
||||
},
|
||||
),
|
||||
ctx: Store,
|
||||
},
|
||||
),
|
||||
ctx: Load,
|
||||
},
|
||||
),
|
||||
NumberLiteral(
|
||||
ExprNumberLiteral {
|
||||
range: 342..343,
|
||||
value: Int(
|
||||
2,
|
||||
value: NumberLiteral(
|
||||
ExprNumberLiteral {
|
||||
range: 342..343,
|
||||
value: Int(
|
||||
2,
|
||||
),
|
||||
},
|
||||
),
|
||||
},
|
||||
),
|
||||
],
|
||||
ctx: Load,
|
||||
parenthesized: false,
|
||||
parenthesized: true,
|
||||
},
|
||||
),
|
||||
},
|
||||
|
@ -1231,7 +1236,7 @@ Module(
|
|||
8 | (*x if True else y, z, *x if True else y)
|
||||
9 | (*lambda x: x, z, *lambda x: x)
|
||||
10 | (*x := 2, z, *x := 2)
|
||||
| ^^ Syntax Error: Starred expression cannot be used here
|
||||
| ^^ Syntax Error: Assignment expression target must be an identifier
|
||||
|
|
||||
|
||||
|
||||
|
@ -1239,34 +1244,7 @@ Module(
|
|||
8 | (*x if True else y, z, *x if True else y)
|
||||
9 | (*lambda x: x, z, *lambda x: x)
|
||||
10 | (*x := 2, z, *x := 2)
|
||||
| ^^ Syntax Error: Expected ')', found ':='
|
||||
|
|
||||
|
||||
|
||||
|
|
||||
8 | (*x if True else y, z, *x if True else y)
|
||||
9 | (*lambda x: x, z, *lambda x: x)
|
||||
10 | (*x := 2, z, *x := 2)
|
||||
| ^^ Syntax Error: Expected ',', found ':='
|
||||
|
|
||||
|
||||
|
||||
|
|
||||
8 | (*x if True else y, z, *x if True else y)
|
||||
9 | (*lambda x: x, z, *lambda x: x)
|
||||
10 | (*x := 2, z, *x := 2)
|
||||
| ^ Syntax Error: Expected a statement
|
||||
|
|
||||
|
||||
|
||||
|
|
||||
8 | (*x if True else y, z, *x if True else y)
|
||||
9 | (*lambda x: x, z, *lambda x: x)
|
||||
10 | (*x := 2, z, *x := 2)
|
||||
| ^ Syntax Error: Expected a statement
|
||||
11 |
|
||||
12 |
|
||||
13 | # Non-parenthesized
|
||||
| ^^ Syntax Error: Assignment expression target must be an identifier
|
||||
|
|
||||
|
||||
|
||||
|
|
|
@ -339,24 +339,29 @@ Module(
|
|||
ExprSet {
|
||||
range: 186..198,
|
||||
elts: [
|
||||
Starred(
|
||||
ExprStarred {
|
||||
range: 187..189,
|
||||
value: Name(
|
||||
ExprName {
|
||||
range: 188..189,
|
||||
id: "x",
|
||||
ctx: Load,
|
||||
Named(
|
||||
ExprNamed {
|
||||
range: 187..194,
|
||||
target: Starred(
|
||||
ExprStarred {
|
||||
range: 187..189,
|
||||
value: Name(
|
||||
ExprName {
|
||||
range: 188..189,
|
||||
id: "x",
|
||||
ctx: Store,
|
||||
},
|
||||
),
|
||||
ctx: Store,
|
||||
},
|
||||
),
|
||||
ctx: Load,
|
||||
},
|
||||
),
|
||||
NumberLiteral(
|
||||
ExprNumberLiteral {
|
||||
range: 193..194,
|
||||
value: Int(
|
||||
2,
|
||||
value: NumberLiteral(
|
||||
ExprNumberLiteral {
|
||||
range: 193..194,
|
||||
value: Int(
|
||||
2,
|
||||
),
|
||||
},
|
||||
),
|
||||
},
|
||||
),
|
||||
|
@ -450,5 +455,5 @@ Module(
|
|||
8 | {*x if True else y, z}
|
||||
9 | {*lambda x: x, z}
|
||||
10 | {*x := 2, z}
|
||||
| ^^ Syntax Error: Expected ',', found ':='
|
||||
| ^^ Syntax Error: Assignment expression target must be an identifier
|
||||
|
|
||||
|
|
|
@ -1,89 +0,0 @@
|
|||
---
|
||||
source: crates/ruff_python_parser/tests/fixtures.rs
|
||||
input_file: crates/ruff_python_parser/resources/inline/err/for_in_target_postfix_expr.py
|
||||
---
|
||||
## AST
|
||||
|
||||
```
|
||||
Module(
|
||||
ModModule {
|
||||
range: 0..29,
|
||||
body: [
|
||||
For(
|
||||
StmtFor {
|
||||
range: 0..28,
|
||||
is_async: false,
|
||||
target: Call(
|
||||
ExprCall {
|
||||
range: 4..13,
|
||||
func: Name(
|
||||
ExprName {
|
||||
range: 4..5,
|
||||
id: "d",
|
||||
ctx: Load,
|
||||
},
|
||||
),
|
||||
arguments: Arguments {
|
||||
range: 5..13,
|
||||
args: [
|
||||
Compare(
|
||||
ExprCompare {
|
||||
range: 6..12,
|
||||
left: Name(
|
||||
ExprName {
|
||||
range: 6..7,
|
||||
id: "x",
|
||||
ctx: Load,
|
||||
},
|
||||
),
|
||||
ops: [
|
||||
In,
|
||||
],
|
||||
comparators: [
|
||||
Name(
|
||||
ExprName {
|
||||
range: 11..12,
|
||||
id: "y",
|
||||
ctx: Load,
|
||||
},
|
||||
),
|
||||
],
|
||||
},
|
||||
),
|
||||
],
|
||||
keywords: [],
|
||||
},
|
||||
},
|
||||
),
|
||||
iter: Name(
|
||||
ExprName {
|
||||
range: 17..23,
|
||||
id: "target",
|
||||
ctx: Load,
|
||||
},
|
||||
),
|
||||
body: [
|
||||
Expr(
|
||||
StmtExpr {
|
||||
range: 25..28,
|
||||
value: EllipsisLiteral(
|
||||
ExprEllipsisLiteral {
|
||||
range: 25..28,
|
||||
},
|
||||
),
|
||||
},
|
||||
),
|
||||
],
|
||||
orelse: [],
|
||||
},
|
||||
),
|
||||
],
|
||||
},
|
||||
)
|
||||
```
|
||||
## Errors
|
||||
|
||||
|
|
||||
1 | for d(x in y) in target: ...
|
||||
| ^^^^^^^^^ Syntax Error: Invalid assignment target
|
||||
|
|
|
@ -7,7 +7,7 @@ input_file: crates/ruff_python_parser/resources/inline/err/for_stmt_invalid_targ
|
|||
```
|
||||
Module(
|
||||
ModModule {
|
||||
range: 0..132,
|
||||
range: 0..154,
|
||||
body: [
|
||||
For(
|
||||
StmtFor {
|
||||
|
@ -233,22 +233,79 @@ Module(
|
|||
),
|
||||
For(
|
||||
StmtFor {
|
||||
range: 100..131,
|
||||
range: 100..121,
|
||||
is_async: false,
|
||||
target: Yield(
|
||||
ExprYield {
|
||||
range: 104..116,
|
||||
value: Some(
|
||||
Compare(
|
||||
ExprCompare {
|
||||
range: 110..116,
|
||||
left: Name(
|
||||
ExprName {
|
||||
range: 110..111,
|
||||
id: "x",
|
||||
ctx: Load,
|
||||
},
|
||||
),
|
||||
ops: [
|
||||
In,
|
||||
],
|
||||
comparators: [
|
||||
Name(
|
||||
ExprName {
|
||||
range: 115..116,
|
||||
id: "y",
|
||||
ctx: Load,
|
||||
},
|
||||
),
|
||||
],
|
||||
},
|
||||
),
|
||||
),
|
||||
},
|
||||
),
|
||||
iter: Name(
|
||||
ExprName {
|
||||
range: 116..116,
|
||||
id: "",
|
||||
ctx: Invalid,
|
||||
},
|
||||
),
|
||||
body: [
|
||||
Expr(
|
||||
StmtExpr {
|
||||
range: 118..121,
|
||||
value: EllipsisLiteral(
|
||||
ExprEllipsisLiteral {
|
||||
range: 118..121,
|
||||
},
|
||||
),
|
||||
},
|
||||
),
|
||||
],
|
||||
orelse: [],
|
||||
},
|
||||
),
|
||||
For(
|
||||
StmtFor {
|
||||
range: 122..153,
|
||||
is_async: false,
|
||||
target: List(
|
||||
ExprList {
|
||||
range: 104..121,
|
||||
range: 126..143,
|
||||
elts: [
|
||||
Name(
|
||||
ExprName {
|
||||
range: 105..106,
|
||||
range: 127..128,
|
||||
id: "x",
|
||||
ctx: Store,
|
||||
},
|
||||
),
|
||||
NumberLiteral(
|
||||
ExprNumberLiteral {
|
||||
range: 108..109,
|
||||
range: 130..131,
|
||||
value: Int(
|
||||
1,
|
||||
),
|
||||
|
@ -256,25 +313,25 @@ Module(
|
|||
),
|
||||
Name(
|
||||
ExprName {
|
||||
range: 111..112,
|
||||
range: 133..134,
|
||||
id: "y",
|
||||
ctx: Store,
|
||||
},
|
||||
),
|
||||
Starred(
|
||||
ExprStarred {
|
||||
range: 114..120,
|
||||
range: 136..142,
|
||||
value: List(
|
||||
ExprList {
|
||||
range: 115..120,
|
||||
range: 137..142,
|
||||
elts: [
|
||||
StringLiteral(
|
||||
ExprStringLiteral {
|
||||
range: 116..119,
|
||||
range: 138..141,
|
||||
value: StringLiteralValue {
|
||||
inner: Single(
|
||||
StringLiteral {
|
||||
range: 116..119,
|
||||
range: 138..141,
|
||||
value: "a",
|
||||
flags: StringLiteralFlags {
|
||||
quote_style: Double,
|
||||
|
@ -299,7 +356,7 @@ Module(
|
|||
),
|
||||
iter: Name(
|
||||
ExprName {
|
||||
range: 125..126,
|
||||
range: 147..148,
|
||||
id: "z",
|
||||
ctx: Load,
|
||||
},
|
||||
|
@ -307,10 +364,10 @@ Module(
|
|||
body: [
|
||||
Expr(
|
||||
StmtExpr {
|
||||
range: 128..131,
|
||||
range: 150..153,
|
||||
value: EllipsisLiteral(
|
||||
ExprEllipsisLiteral {
|
||||
range: 128..131,
|
||||
range: 150..153,
|
||||
},
|
||||
),
|
||||
},
|
||||
|
@ -358,7 +415,7 @@ Module(
|
|||
4 | for *x | y in z: ...
|
||||
| ^^^^^ Syntax Error: Invalid assignment target
|
||||
5 | for await x in z: ...
|
||||
6 | for [x, 1, y, *["a"]] in z: ...
|
||||
6 | for yield x in y: ...
|
||||
|
|
||||
|
||||
|
||||
|
@ -367,21 +424,40 @@ Module(
|
|||
4 | for *x | y in z: ...
|
||||
5 | for await x in z: ...
|
||||
| ^^^^^^^ Syntax Error: Invalid assignment target
|
||||
6 | for [x, 1, y, *["a"]] in z: ...
|
||||
6 | for yield x in y: ...
|
||||
7 | for [x, 1, y, *["a"]] in z: ...
|
||||
|
|
||||
|
||||
|
||||
|
|
||||
4 | for *x | y in z: ...
|
||||
5 | for await x in z: ...
|
||||
6 | for [x, 1, y, *["a"]] in z: ...
|
||||
6 | for yield x in y: ...
|
||||
| ^^^^^^^^^^^^ Syntax Error: Yield expression cannot be used here
|
||||
7 | for [x, 1, y, *["a"]] in z: ...
|
||||
|
|
||||
|
||||
|
||||
|
|
||||
4 | for *x | y in z: ...
|
||||
5 | for await x in z: ...
|
||||
6 | for yield x in y: ...
|
||||
| ^ Syntax Error: Expected 'in', found ':'
|
||||
7 | for [x, 1, y, *["a"]] in z: ...
|
||||
|
|
||||
|
||||
|
||||
|
|
||||
5 | for await x in z: ...
|
||||
6 | for yield x in y: ...
|
||||
7 | for [x, 1, y, *["a"]] in z: ...
|
||||
| ^ Syntax Error: Invalid assignment target
|
||||
|
|
||||
|
||||
|
||||
|
|
||||
4 | for *x | y in z: ...
|
||||
5 | for await x in z: ...
|
||||
6 | for [x, 1, y, *["a"]] in z: ...
|
||||
6 | for yield x in y: ...
|
||||
7 | for [x, 1, y, *["a"]] in z: ...
|
||||
| ^^^ Syntax Error: Invalid assignment target
|
||||
|
|
||||
|
|
|
@ -0,0 +1,341 @@
|
|||
---
|
||||
source: crates/ruff_python_parser/tests/fixtures.rs
|
||||
input_file: crates/ruff_python_parser/resources/inline/err/for_stmt_invalid_target_binary_expr.py
|
||||
---
|
||||
## AST
|
||||
|
||||
```
|
||||
Module(
|
||||
ModModule {
|
||||
range: 0..124,
|
||||
body: [
|
||||
For(
|
||||
StmtFor {
|
||||
range: 0..24,
|
||||
is_async: false,
|
||||
target: Compare(
|
||||
ExprCompare {
|
||||
range: 4..14,
|
||||
left: Name(
|
||||
ExprName {
|
||||
range: 4..5,
|
||||
id: "x",
|
||||
ctx: Load,
|
||||
},
|
||||
),
|
||||
ops: [
|
||||
NotIn,
|
||||
],
|
||||
comparators: [
|
||||
Name(
|
||||
ExprName {
|
||||
range: 13..14,
|
||||
id: "y",
|
||||
ctx: Load,
|
||||
},
|
||||
),
|
||||
],
|
||||
},
|
||||
),
|
||||
iter: Name(
|
||||
ExprName {
|
||||
range: 18..19,
|
||||
id: "z",
|
||||
ctx: Load,
|
||||
},
|
||||
),
|
||||
body: [
|
||||
Expr(
|
||||
StmtExpr {
|
||||
range: 21..24,
|
||||
value: EllipsisLiteral(
|
||||
ExprEllipsisLiteral {
|
||||
range: 21..24,
|
||||
},
|
||||
),
|
||||
},
|
||||
),
|
||||
],
|
||||
orelse: [],
|
||||
},
|
||||
),
|
||||
For(
|
||||
StmtFor {
|
||||
range: 25..45,
|
||||
is_async: false,
|
||||
target: Compare(
|
||||
ExprCompare {
|
||||
range: 29..35,
|
||||
left: Name(
|
||||
ExprName {
|
||||
range: 29..30,
|
||||
id: "x",
|
||||
ctx: Load,
|
||||
},
|
||||
),
|
||||
ops: [
|
||||
Eq,
|
||||
],
|
||||
comparators: [
|
||||
Name(
|
||||
ExprName {
|
||||
range: 34..35,
|
||||
id: "y",
|
||||
ctx: Load,
|
||||
},
|
||||
),
|
||||
],
|
||||
},
|
||||
),
|
||||
iter: Name(
|
||||
ExprName {
|
||||
range: 39..40,
|
||||
id: "z",
|
||||
ctx: Load,
|
||||
},
|
||||
),
|
||||
body: [
|
||||
Expr(
|
||||
StmtExpr {
|
||||
range: 42..45,
|
||||
value: EllipsisLiteral(
|
||||
ExprEllipsisLiteral {
|
||||
range: 42..45,
|
||||
},
|
||||
),
|
||||
},
|
||||
),
|
||||
],
|
||||
orelse: [],
|
||||
},
|
||||
),
|
||||
For(
|
||||
StmtFor {
|
||||
range: 46..66,
|
||||
is_async: false,
|
||||
target: BoolOp(
|
||||
ExprBoolOp {
|
||||
range: 50..56,
|
||||
op: Or,
|
||||
values: [
|
||||
Name(
|
||||
ExprName {
|
||||
range: 50..51,
|
||||
id: "x",
|
||||
ctx: Load,
|
||||
},
|
||||
),
|
||||
Name(
|
||||
ExprName {
|
||||
range: 55..56,
|
||||
id: "y",
|
||||
ctx: Load,
|
||||
},
|
||||
),
|
||||
],
|
||||
},
|
||||
),
|
||||
iter: Name(
|
||||
ExprName {
|
||||
range: 60..61,
|
||||
id: "z",
|
||||
ctx: Load,
|
||||
},
|
||||
),
|
||||
body: [
|
||||
Expr(
|
||||
StmtExpr {
|
||||
range: 63..66,
|
||||
value: EllipsisLiteral(
|
||||
ExprEllipsisLiteral {
|
||||
range: 63..66,
|
||||
},
|
||||
),
|
||||
},
|
||||
),
|
||||
],
|
||||
orelse: [],
|
||||
},
|
||||
),
|
||||
For(
|
||||
StmtFor {
|
||||
range: 67..83,
|
||||
is_async: false,
|
||||
target: UnaryOp(
|
||||
ExprUnaryOp {
|
||||
range: 71..73,
|
||||
op: USub,
|
||||
operand: Name(
|
||||
ExprName {
|
||||
range: 72..73,
|
||||
id: "x",
|
||||
ctx: Store,
|
||||
},
|
||||
),
|
||||
},
|
||||
),
|
||||
iter: Name(
|
||||
ExprName {
|
||||
range: 77..78,
|
||||
id: "y",
|
||||
ctx: Load,
|
||||
},
|
||||
),
|
||||
body: [
|
||||
Expr(
|
||||
StmtExpr {
|
||||
range: 80..83,
|
||||
value: EllipsisLiteral(
|
||||
ExprEllipsisLiteral {
|
||||
range: 80..83,
|
||||
},
|
||||
),
|
||||
},
|
||||
),
|
||||
],
|
||||
orelse: [],
|
||||
},
|
||||
),
|
||||
For(
|
||||
StmtFor {
|
||||
range: 84..103,
|
||||
is_async: false,
|
||||
target: UnaryOp(
|
||||
ExprUnaryOp {
|
||||
range: 88..93,
|
||||
op: Not,
|
||||
operand: Name(
|
||||
ExprName {
|
||||
range: 92..93,
|
||||
id: "x",
|
||||
ctx: Store,
|
||||
},
|
||||
),
|
||||
},
|
||||
),
|
||||
iter: Name(
|
||||
ExprName {
|
||||
range: 97..98,
|
||||
id: "y",
|
||||
ctx: Load,
|
||||
},
|
||||
),
|
||||
body: [
|
||||
Expr(
|
||||
StmtExpr {
|
||||
range: 100..103,
|
||||
value: EllipsisLiteral(
|
||||
ExprEllipsisLiteral {
|
||||
range: 100..103,
|
||||
},
|
||||
),
|
||||
},
|
||||
),
|
||||
],
|
||||
orelse: [],
|
||||
},
|
||||
),
|
||||
For(
|
||||
StmtFor {
|
||||
range: 104..123,
|
||||
is_async: false,
|
||||
target: BinOp(
|
||||
ExprBinOp {
|
||||
range: 108..113,
|
||||
left: Name(
|
||||
ExprName {
|
||||
range: 108..109,
|
||||
id: "x",
|
||||
ctx: Load,
|
||||
},
|
||||
),
|
||||
op: BitOr,
|
||||
right: Name(
|
||||
ExprName {
|
||||
range: 112..113,
|
||||
id: "y",
|
||||
ctx: Load,
|
||||
},
|
||||
),
|
||||
},
|
||||
),
|
||||
iter: Name(
|
||||
ExprName {
|
||||
range: 117..118,
|
||||
id: "z",
|
||||
ctx: Load,
|
||||
},
|
||||
),
|
||||
body: [
|
||||
Expr(
|
||||
StmtExpr {
|
||||
range: 120..123,
|
||||
value: EllipsisLiteral(
|
||||
ExprEllipsisLiteral {
|
||||
range: 120..123,
|
||||
},
|
||||
),
|
||||
},
|
||||
),
|
||||
],
|
||||
orelse: [],
|
||||
},
|
||||
),
|
||||
],
|
||||
},
|
||||
)
|
||||
```
|
||||
## Errors
|
||||
|
||||
|
|
||||
1 | for x not in y in z: ...
|
||||
| ^^^^^^^^^^ Syntax Error: Invalid assignment target
|
||||
2 | for x == y in z: ...
|
||||
3 | for x or y in z: ...
|
||||
|
|
||||
|
||||
|
||||
|
|
||||
1 | for x not in y in z: ...
|
||||
2 | for x == y in z: ...
|
||||
| ^^^^^^ Syntax Error: Invalid assignment target
|
||||
3 | for x or y in z: ...
|
||||
4 | for -x in y: ...
|
||||
|
|
||||
|
||||
|
||||
|
|
||||
1 | for x not in y in z: ...
|
||||
2 | for x == y in z: ...
|
||||
3 | for x or y in z: ...
|
||||
| ^^^^^^ Syntax Error: Invalid assignment target
|
||||
4 | for -x in y: ...
|
||||
5 | for not x in y: ...
|
||||
|
|
||||
|
||||
|
||||
|
|
||||
2 | for x == y in z: ...
|
||||
3 | for x or y in z: ...
|
||||
4 | for -x in y: ...
|
||||
| ^^ Syntax Error: Invalid assignment target
|
||||
5 | for not x in y: ...
|
||||
6 | for x | y in z: ...
|
||||
|
|
||||
|
||||
|
||||
|
|
||||
3 | for x or y in z: ...
|
||||
4 | for -x in y: ...
|
||||
5 | for not x in y: ...
|
||||
| ^^^^^ Syntax Error: Invalid assignment target
|
||||
6 | for x | y in z: ...
|
||||
|
|
||||
|
||||
|
||||
|
|
||||
4 | for -x in y: ...
|
||||
5 | for not x in y: ...
|
||||
6 | for x | y in z: ...
|
||||
| ^^^^^ Syntax Error: Invalid assignment target
|
||||
|
|
|
@ -1,27 +1,95 @@
|
|||
---
|
||||
source: crates/ruff_python_parser/tests/fixtures.rs
|
||||
input_file: crates/ruff_python_parser/resources/inline/err/parenthesized_compare_expr_in_for.py
|
||||
input_file: crates/ruff_python_parser/resources/inline/err/for_stmt_invalid_target_in_keyword.py
|
||||
---
|
||||
## AST
|
||||
|
||||
```
|
||||
Module(
|
||||
ModModule {
|
||||
range: 0..141,
|
||||
range: 0..170,
|
||||
body: [
|
||||
For(
|
||||
StmtFor {
|
||||
range: 0..27,
|
||||
range: 0..28,
|
||||
is_async: false,
|
||||
target: Call(
|
||||
ExprCall {
|
||||
range: 4..14,
|
||||
range: 4..13,
|
||||
func: Name(
|
||||
ExprName {
|
||||
range: 4..5,
|
||||
id: "d",
|
||||
ctx: Load,
|
||||
},
|
||||
),
|
||||
arguments: Arguments {
|
||||
range: 5..13,
|
||||
args: [
|
||||
Compare(
|
||||
ExprCompare {
|
||||
range: 6..12,
|
||||
left: Name(
|
||||
ExprName {
|
||||
range: 6..7,
|
||||
id: "x",
|
||||
ctx: Load,
|
||||
},
|
||||
),
|
||||
ops: [
|
||||
In,
|
||||
],
|
||||
comparators: [
|
||||
Name(
|
||||
ExprName {
|
||||
range: 11..12,
|
||||
id: "y",
|
||||
ctx: Load,
|
||||
},
|
||||
),
|
||||
],
|
||||
},
|
||||
),
|
||||
],
|
||||
keywords: [],
|
||||
},
|
||||
},
|
||||
),
|
||||
iter: Name(
|
||||
ExprName {
|
||||
range: 17..23,
|
||||
id: "target",
|
||||
ctx: Load,
|
||||
},
|
||||
),
|
||||
body: [
|
||||
Expr(
|
||||
StmtExpr {
|
||||
range: 25..28,
|
||||
value: EllipsisLiteral(
|
||||
ExprEllipsisLiteral {
|
||||
range: 25..28,
|
||||
},
|
||||
),
|
||||
},
|
||||
),
|
||||
],
|
||||
orelse: [],
|
||||
},
|
||||
),
|
||||
For(
|
||||
StmtFor {
|
||||
range: 29..56,
|
||||
is_async: false,
|
||||
target: Call(
|
||||
ExprCall {
|
||||
range: 33..43,
|
||||
func: Compare(
|
||||
ExprCompare {
|
||||
range: 5..11,
|
||||
range: 34..40,
|
||||
left: Name(
|
||||
ExprName {
|
||||
range: 5..6,
|
||||
range: 34..35,
|
||||
id: "x",
|
||||
ctx: Load,
|
||||
},
|
||||
|
@ -32,7 +100,7 @@ Module(
|
|||
comparators: [
|
||||
Name(
|
||||
ExprName {
|
||||
range: 10..11,
|
||||
range: 39..40,
|
||||
id: "y",
|
||||
ctx: Load,
|
||||
},
|
||||
|
@ -41,7 +109,7 @@ Module(
|
|||
},
|
||||
),
|
||||
arguments: Arguments {
|
||||
range: 12..14,
|
||||
range: 41..43,
|
||||
args: [],
|
||||
keywords: [],
|
||||
},
|
||||
|
@ -49,7 +117,7 @@ Module(
|
|||
),
|
||||
iter: Name(
|
||||
ExprName {
|
||||
range: 18..22,
|
||||
range: 47..51,
|
||||
id: "iter",
|
||||
ctx: Load,
|
||||
},
|
||||
|
@ -57,10 +125,10 @@ Module(
|
|||
body: [
|
||||
Expr(
|
||||
StmtExpr {
|
||||
range: 24..27,
|
||||
range: 53..56,
|
||||
value: EllipsisLiteral(
|
||||
ExprEllipsisLiteral {
|
||||
range: 24..27,
|
||||
range: 53..56,
|
||||
},
|
||||
),
|
||||
},
|
||||
|
@ -71,14 +139,14 @@ Module(
|
|||
),
|
||||
For(
|
||||
StmtFor {
|
||||
range: 28..53,
|
||||
range: 57..82,
|
||||
is_async: false,
|
||||
target: Compare(
|
||||
ExprCompare {
|
||||
range: 33..39,
|
||||
range: 62..68,
|
||||
left: Name(
|
||||
ExprName {
|
||||
range: 33..34,
|
||||
range: 62..63,
|
||||
id: "x",
|
||||
ctx: Load,
|
||||
},
|
||||
|
@ -89,7 +157,7 @@ Module(
|
|||
comparators: [
|
||||
Name(
|
||||
ExprName {
|
||||
range: 38..39,
|
||||
range: 67..68,
|
||||
id: "y",
|
||||
ctx: Load,
|
||||
},
|
||||
|
@ -97,72 +165,6 @@ Module(
|
|||
],
|
||||
},
|
||||
),
|
||||
iter: Name(
|
||||
ExprName {
|
||||
range: 44..48,
|
||||
id: "iter",
|
||||
ctx: Load,
|
||||
},
|
||||
),
|
||||
body: [
|
||||
Expr(
|
||||
StmtExpr {
|
||||
range: 50..53,
|
||||
value: EllipsisLiteral(
|
||||
ExprEllipsisLiteral {
|
||||
range: 50..53,
|
||||
},
|
||||
),
|
||||
},
|
||||
),
|
||||
],
|
||||
orelse: [],
|
||||
},
|
||||
),
|
||||
For(
|
||||
StmtFor {
|
||||
range: 54..82,
|
||||
is_async: false,
|
||||
target: Tuple(
|
||||
ExprTuple {
|
||||
range: 58..69,
|
||||
elts: [
|
||||
Compare(
|
||||
ExprCompare {
|
||||
range: 59..65,
|
||||
left: Name(
|
||||
ExprName {
|
||||
range: 59..60,
|
||||
id: "x",
|
||||
ctx: Load,
|
||||
},
|
||||
),
|
||||
ops: [
|
||||
In,
|
||||
],
|
||||
comparators: [
|
||||
Name(
|
||||
ExprName {
|
||||
range: 64..65,
|
||||
id: "y",
|
||||
ctx: Load,
|
||||
},
|
||||
),
|
||||
],
|
||||
},
|
||||
),
|
||||
Name(
|
||||
ExprName {
|
||||
range: 67..68,
|
||||
id: "z",
|
||||
ctx: Store,
|
||||
},
|
||||
),
|
||||
],
|
||||
ctx: Store,
|
||||
parenthesized: true,
|
||||
},
|
||||
),
|
||||
iter: Name(
|
||||
ExprName {
|
||||
range: 73..77,
|
||||
|
@ -189,8 +191,8 @@ Module(
|
|||
StmtFor {
|
||||
range: 83..111,
|
||||
is_async: false,
|
||||
target: List(
|
||||
ExprList {
|
||||
target: Tuple(
|
||||
ExprTuple {
|
||||
range: 87..98,
|
||||
elts: [
|
||||
Compare(
|
||||
|
@ -226,6 +228,7 @@ Module(
|
|||
),
|
||||
],
|
||||
ctx: Store,
|
||||
parenthesized: true,
|
||||
},
|
||||
),
|
||||
iter: Name(
|
||||
|
@ -254,8 +257,8 @@ Module(
|
|||
StmtFor {
|
||||
range: 112..140,
|
||||
is_async: false,
|
||||
target: Set(
|
||||
ExprSet {
|
||||
target: List(
|
||||
ExprList {
|
||||
range: 116..127,
|
||||
elts: [
|
||||
Compare(
|
||||
|
@ -286,10 +289,11 @@ Module(
|
|||
ExprName {
|
||||
range: 125..126,
|
||||
id: "z",
|
||||
ctx: Load,
|
||||
ctx: Store,
|
||||
},
|
||||
),
|
||||
],
|
||||
ctx: Store,
|
||||
},
|
||||
),
|
||||
iter: Name(
|
||||
|
@ -314,6 +318,70 @@ Module(
|
|||
orelse: [],
|
||||
},
|
||||
),
|
||||
For(
|
||||
StmtFor {
|
||||
range: 141..169,
|
||||
is_async: false,
|
||||
target: Set(
|
||||
ExprSet {
|
||||
range: 145..156,
|
||||
elts: [
|
||||
Compare(
|
||||
ExprCompare {
|
||||
range: 146..152,
|
||||
left: Name(
|
||||
ExprName {
|
||||
range: 146..147,
|
||||
id: "x",
|
||||
ctx: Load,
|
||||
},
|
||||
),
|
||||
ops: [
|
||||
In,
|
||||
],
|
||||
comparators: [
|
||||
Name(
|
||||
ExprName {
|
||||
range: 151..152,
|
||||
id: "y",
|
||||
ctx: Load,
|
||||
},
|
||||
),
|
||||
],
|
||||
},
|
||||
),
|
||||
Name(
|
||||
ExprName {
|
||||
range: 154..155,
|
||||
id: "z",
|
||||
ctx: Load,
|
||||
},
|
||||
),
|
||||
],
|
||||
},
|
||||
),
|
||||
iter: Name(
|
||||
ExprName {
|
||||
range: 160..164,
|
||||
id: "iter",
|
||||
ctx: Load,
|
||||
},
|
||||
),
|
||||
body: [
|
||||
Expr(
|
||||
StmtExpr {
|
||||
range: 166..169,
|
||||
value: EllipsisLiteral(
|
||||
ExprEllipsisLiteral {
|
||||
range: 166..169,
|
||||
},
|
||||
),
|
||||
},
|
||||
),
|
||||
],
|
||||
orelse: [],
|
||||
},
|
||||
),
|
||||
],
|
||||
},
|
||||
)
|
||||
|
@ -321,44 +389,54 @@ Module(
|
|||
## Errors
|
||||
|
||||
|
|
||||
1 | for (x in y)() in iter: ...
|
||||
1 | for d(x in y) in target: ...
|
||||
| ^^^^^^^^^ Syntax Error: Invalid assignment target
|
||||
2 | for (x in y)() in iter: ...
|
||||
3 | for (x in y) in iter: ...
|
||||
|
|
||||
|
||||
|
||||
|
|
||||
1 | for d(x in y) in target: ...
|
||||
2 | for (x in y)() in iter: ...
|
||||
| ^^^^^^^^^^ Syntax Error: Invalid assignment target
|
||||
2 | for (x in y) in iter: ...
|
||||
3 | for (x in y, z) in iter: ...
|
||||
3 | for (x in y) in iter: ...
|
||||
4 | for (x in y, z) in iter: ...
|
||||
|
|
||||
|
||||
|
||||
|
|
||||
1 | for (x in y)() in iter: ...
|
||||
2 | for (x in y) in iter: ...
|
||||
1 | for d(x in y) in target: ...
|
||||
2 | for (x in y)() in iter: ...
|
||||
3 | for (x in y) in iter: ...
|
||||
| ^^^^^^ Syntax Error: Invalid assignment target
|
||||
3 | for (x in y, z) in iter: ...
|
||||
4 | for [x in y, z] in iter: ...
|
||||
4 | for (x in y, z) in iter: ...
|
||||
5 | for [x in y, z] in iter: ...
|
||||
|
|
||||
|
||||
|
||||
|
|
||||
1 | for (x in y)() in iter: ...
|
||||
2 | for (x in y) in iter: ...
|
||||
3 | for (x in y, z) in iter: ...
|
||||
2 | for (x in y)() in iter: ...
|
||||
3 | for (x in y) in iter: ...
|
||||
4 | for (x in y, z) in iter: ...
|
||||
| ^^^^^^ Syntax Error: Invalid assignment target
|
||||
4 | for [x in y, z] in iter: ...
|
||||
5 | for {x in y, z} in iter: ...
|
||||
5 | for [x in y, z] in iter: ...
|
||||
6 | for {x in y, z} in iter: ...
|
||||
|
|
||||
|
||||
|
||||
|
|
||||
2 | for (x in y) in iter: ...
|
||||
3 | for (x in y, z) in iter: ...
|
||||
4 | for [x in y, z] in iter: ...
|
||||
3 | for (x in y) in iter: ...
|
||||
4 | for (x in y, z) in iter: ...
|
||||
5 | for [x in y, z] in iter: ...
|
||||
| ^^^^^^ Syntax Error: Invalid assignment target
|
||||
5 | for {x in y, z} in iter: ...
|
||||
6 | for {x in y, z} in iter: ...
|
||||
|
|
||||
|
||||
|
||||
|
|
||||
3 | for (x in y, z) in iter: ...
|
||||
4 | for [x in y, z] in iter: ...
|
||||
5 | for {x in y, z} in iter: ...
|
||||
4 | for (x in y, z) in iter: ...
|
||||
5 | for [x in y, z] in iter: ...
|
||||
6 | for {x in y, z} in iter: ...
|
||||
| ^^^^^^^^^^^ Syntax Error: Invalid assignment target
|
||||
|
|
|
@ -1,78 +0,0 @@
|
|||
---
|
||||
source: crates/ruff_python_parser/tests/fixtures.rs
|
||||
input_file: crates/ruff_python_parser/resources/inline/ok/for_in_target_postfix_expr.py
|
||||
---
|
||||
## AST
|
||||
|
||||
```
|
||||
Module(
|
||||
ModModule {
|
||||
range: 0..29,
|
||||
body: [
|
||||
For(
|
||||
StmtFor {
|
||||
range: 0..28,
|
||||
is_async: false,
|
||||
target: Subscript(
|
||||
ExprSubscript {
|
||||
range: 4..13,
|
||||
value: Name(
|
||||
ExprName {
|
||||
range: 4..5,
|
||||
id: "d",
|
||||
ctx: Load,
|
||||
},
|
||||
),
|
||||
slice: Compare(
|
||||
ExprCompare {
|
||||
range: 6..12,
|
||||
left: Name(
|
||||
ExprName {
|
||||
range: 6..7,
|
||||
id: "x",
|
||||
ctx: Load,
|
||||
},
|
||||
),
|
||||
ops: [
|
||||
In,
|
||||
],
|
||||
comparators: [
|
||||
Name(
|
||||
ExprName {
|
||||
range: 11..12,
|
||||
id: "y",
|
||||
ctx: Load,
|
||||
},
|
||||
),
|
||||
],
|
||||
},
|
||||
),
|
||||
ctx: Store,
|
||||
},
|
||||
),
|
||||
iter: Name(
|
||||
ExprName {
|
||||
range: 17..23,
|
||||
id: "target",
|
||||
ctx: Load,
|
||||
},
|
||||
),
|
||||
body: [
|
||||
Expr(
|
||||
StmtExpr {
|
||||
range: 25..28,
|
||||
value: EllipsisLiteral(
|
||||
ExprEllipsisLiteral {
|
||||
range: 25..28,
|
||||
},
|
||||
),
|
||||
},
|
||||
),
|
||||
],
|
||||
orelse: [],
|
||||
},
|
||||
),
|
||||
],
|
||||
},
|
||||
)
|
||||
```
|
|
@ -1,13 +1,13 @@
|
|||
---
|
||||
source: crates/ruff_python_parser/tests/fixtures.rs
|
||||
input_file: crates/ruff_python_parser/resources/inline/ok/parenthesized_compare_expr_in_for.py
|
||||
input_file: crates/ruff_python_parser/resources/inline/ok/for_in_target_valid_expr.py
|
||||
---
|
||||
## AST
|
||||
|
||||
```
|
||||
Module(
|
||||
ModModule {
|
||||
range: 0..60,
|
||||
range: 0..89,
|
||||
body: [
|
||||
For(
|
||||
StmtFor {
|
||||
|
@ -15,13 +15,20 @@ Module(
|
|||
is_async: false,
|
||||
target: Subscript(
|
||||
ExprSubscript {
|
||||
range: 4..15,
|
||||
value: Compare(
|
||||
range: 4..13,
|
||||
value: Name(
|
||||
ExprName {
|
||||
range: 4..5,
|
||||
id: "d",
|
||||
ctx: Load,
|
||||
},
|
||||
),
|
||||
slice: Compare(
|
||||
ExprCompare {
|
||||
range: 5..11,
|
||||
range: 6..12,
|
||||
left: Name(
|
||||
ExprName {
|
||||
range: 5..6,
|
||||
range: 6..7,
|
||||
id: "x",
|
||||
ctx: Load,
|
||||
},
|
||||
|
@ -32,7 +39,7 @@ Module(
|
|||
comparators: [
|
||||
Name(
|
||||
ExprName {
|
||||
range: 10..11,
|
||||
range: 11..12,
|
||||
id: "y",
|
||||
ctx: Load,
|
||||
},
|
||||
|
@ -40,21 +47,13 @@ Module(
|
|||
],
|
||||
},
|
||||
),
|
||||
slice: NumberLiteral(
|
||||
ExprNumberLiteral {
|
||||
range: 13..14,
|
||||
value: Int(
|
||||
0,
|
||||
),
|
||||
},
|
||||
),
|
||||
ctx: Store,
|
||||
},
|
||||
),
|
||||
iter: Name(
|
||||
ExprName {
|
||||
range: 19..23,
|
||||
id: "iter",
|
||||
range: 17..23,
|
||||
id: "target",
|
||||
ctx: Load,
|
||||
},
|
||||
),
|
||||
|
@ -75,11 +74,11 @@ Module(
|
|||
),
|
||||
For(
|
||||
StmtFor {
|
||||
range: 29..59,
|
||||
range: 29..57,
|
||||
is_async: false,
|
||||
target: Attribute(
|
||||
ExprAttribute {
|
||||
range: 33..46,
|
||||
target: Subscript(
|
||||
ExprSubscript {
|
||||
range: 33..44,
|
||||
value: Compare(
|
||||
ExprCompare {
|
||||
range: 34..40,
|
||||
|
@ -104,16 +103,20 @@ Module(
|
|||
],
|
||||
},
|
||||
),
|
||||
attr: Identifier {
|
||||
id: "attr",
|
||||
range: 42..46,
|
||||
},
|
||||
slice: NumberLiteral(
|
||||
ExprNumberLiteral {
|
||||
range: 42..43,
|
||||
value: Int(
|
||||
0,
|
||||
),
|
||||
},
|
||||
),
|
||||
ctx: Store,
|
||||
},
|
||||
),
|
||||
iter: Name(
|
||||
ExprName {
|
||||
range: 50..54,
|
||||
range: 48..52,
|
||||
id: "iter",
|
||||
ctx: Load,
|
||||
},
|
||||
|
@ -121,10 +124,70 @@ Module(
|
|||
body: [
|
||||
Expr(
|
||||
StmtExpr {
|
||||
range: 56..59,
|
||||
range: 54..57,
|
||||
value: EllipsisLiteral(
|
||||
ExprEllipsisLiteral {
|
||||
range: 56..59,
|
||||
range: 54..57,
|
||||
},
|
||||
),
|
||||
},
|
||||
),
|
||||
],
|
||||
orelse: [],
|
||||
},
|
||||
),
|
||||
For(
|
||||
StmtFor {
|
||||
range: 58..88,
|
||||
is_async: false,
|
||||
target: Attribute(
|
||||
ExprAttribute {
|
||||
range: 62..75,
|
||||
value: Compare(
|
||||
ExprCompare {
|
||||
range: 63..69,
|
||||
left: Name(
|
||||
ExprName {
|
||||
range: 63..64,
|
||||
id: "x",
|
||||
ctx: Load,
|
||||
},
|
||||
),
|
||||
ops: [
|
||||
In,
|
||||
],
|
||||
comparators: [
|
||||
Name(
|
||||
ExprName {
|
||||
range: 68..69,
|
||||
id: "y",
|
||||
ctx: Load,
|
||||
},
|
||||
),
|
||||
],
|
||||
},
|
||||
),
|
||||
attr: Identifier {
|
||||
id: "attr",
|
||||
range: 71..75,
|
||||
},
|
||||
ctx: Store,
|
||||
},
|
||||
),
|
||||
iter: Name(
|
||||
ExprName {
|
||||
range: 79..83,
|
||||
id: "iter",
|
||||
ctx: Load,
|
||||
},
|
||||
),
|
||||
body: [
|
||||
Expr(
|
||||
StmtExpr {
|
||||
range: 85..88,
|
||||
value: EllipsisLiteral(
|
||||
ExprEllipsisLiteral {
|
||||
range: 85..88,
|
||||
},
|
||||
),
|
||||
},
|
Loading…
Add table
Add a link
Reference in a new issue