Compare commits
3 Commits
dcreager/f
...
dhruv/refa
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c0fc84fd78 | ||
|
|
060141b1de | ||
|
|
b04cb9f92a |
1
Cargo.lock
generated
1
Cargo.lock
generated
@@ -2180,7 +2180,6 @@ dependencies = [
|
||||
"anyhow",
|
||||
"bitflags 2.5.0",
|
||||
"bstr",
|
||||
"drop_bomb",
|
||||
"insta",
|
||||
"is-macro",
|
||||
"itertools 0.12.1",
|
||||
|
||||
@@ -18,7 +18,6 @@ ruff_text_size = { path = "../ruff_text_size" }
|
||||
|
||||
anyhow = { workspace = true }
|
||||
bitflags = { workspace = true }
|
||||
drop_bomb = { workspace = true }
|
||||
bstr = { workspace = true }
|
||||
is-macro = { workspace = true }
|
||||
itertools = { workspace = true }
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
for d(x in y) in target: ...
|
||||
@@ -3,4 +3,5 @@ for "a" in x: ...
|
||||
for *x and y in z: ...
|
||||
for *x | y in z: ...
|
||||
for await x in z: ...
|
||||
for yield x in y: ...
|
||||
for [x, 1, y, *["a"]] in z: ...
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
for x not in y in z: ...
|
||||
for x == y in z: ...
|
||||
for x or y in z: ...
|
||||
for -x in y: ...
|
||||
for not x in y: ...
|
||||
for x | y in z: ...
|
||||
@@ -1,3 +1,4 @@
|
||||
for d(x in y) in target: ...
|
||||
for (x in y)() in iter: ...
|
||||
for (x in y) in iter: ...
|
||||
for (x in y, z) in iter: ...
|
||||
@@ -1 +0,0 @@
|
||||
for d[x in y] in target: ...
|
||||
@@ -1,2 +1,3 @@
|
||||
for d[x in y] in target: ...
|
||||
for (x in y)[0] in iter: ...
|
||||
for (x in y).attr in iter: ...
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,7 +1,6 @@
|
||||
use std::cmp::Ordering;
|
||||
|
||||
use bitflags::bitflags;
|
||||
use drop_bomb::DebugDropBomb;
|
||||
|
||||
use ast::Mod;
|
||||
use ruff_python_ast as ast;
|
||||
@@ -16,7 +15,7 @@ use crate::{
|
||||
Mode, ParseError, ParseErrorType, Tok, TokenKind,
|
||||
};
|
||||
|
||||
use self::expression::AllowStarredExpression;
|
||||
use self::expression::ExpressionContext;
|
||||
|
||||
mod expression;
|
||||
mod helpers;
|
||||
@@ -77,13 +76,6 @@ pub(crate) struct Parser<'src> {
|
||||
/// Stores all the syntax errors found during the parsing.
|
||||
errors: Vec<ParseError>,
|
||||
|
||||
/// This tracks the current expression or statement being parsed.
|
||||
///
|
||||
/// The `ctx` is also used to create custom error messages and forbid certain
|
||||
/// expressions or statements of being parsed. The `ctx` should be empty after
|
||||
/// an expression or statement is done parsing.
|
||||
ctx: ParserCtxFlags,
|
||||
|
||||
/// Specify the mode in which the code will be parsed.
|
||||
mode: Mode,
|
||||
|
||||
@@ -123,7 +115,6 @@ impl<'src> Parser<'src> {
|
||||
mode,
|
||||
source,
|
||||
errors: Vec::new(),
|
||||
ctx: ParserCtxFlags::empty(),
|
||||
tokens,
|
||||
recovery_context: RecoveryContext::empty(),
|
||||
last_token_end: tokens_range.start(),
|
||||
@@ -136,7 +127,7 @@ impl<'src> Parser<'src> {
|
||||
pub(crate) fn parse_program(mut self) -> Program {
|
||||
let ast = if self.mode == Mode::Expression {
|
||||
let start = self.node_start();
|
||||
let parsed_expr = self.parse_expression_list(AllowStarredExpression::No);
|
||||
let parsed_expr = self.parse_expression_list(ExpressionContext::default());
|
||||
|
||||
// All of the remaining newlines are actually going to be non-logical newlines.
|
||||
self.eat(TokenKind::Newline);
|
||||
@@ -185,9 +176,6 @@ impl<'src> Parser<'src> {
|
||||
}
|
||||
|
||||
fn finish(self) -> Vec<ParseError> {
|
||||
// After parsing, the `ctx` and `ctx_stack` should be empty.
|
||||
// If it's not, you probably forgot to call `clear_ctx` somewhere.
|
||||
assert_eq!(self.ctx, ParserCtxFlags::empty());
|
||||
assert_eq!(
|
||||
self.current_token_kind(),
|
||||
TokenKind::EndOfFile,
|
||||
@@ -232,29 +220,6 @@ impl<'src> Parser<'src> {
|
||||
merged
|
||||
}
|
||||
|
||||
#[inline]
|
||||
#[must_use]
|
||||
fn set_ctx(&mut self, ctx: ParserCtxFlags) -> SavedParserContext {
|
||||
SavedParserContext {
|
||||
flags: std::mem::replace(&mut self.ctx, ctx),
|
||||
bomb: DebugDropBomb::new(
|
||||
"You must restore the old parser context explicit by calling `restore_ctx`",
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn restore_ctx(&mut self, current: ParserCtxFlags, mut saved_context: SavedParserContext) {
|
||||
assert_eq!(self.ctx, current);
|
||||
saved_context.bomb.defuse();
|
||||
self.ctx = saved_context.flags;
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn has_ctx(&self, ctx: ParserCtxFlags) -> bool {
|
||||
self.ctx.intersects(ctx)
|
||||
}
|
||||
|
||||
/// Returns the start position for a node that starts at the current token.
|
||||
fn node_start(&self) -> TextSize {
|
||||
self.current_token_range().start()
|
||||
@@ -675,13 +640,6 @@ impl SequenceMatchPatternParentheses {
|
||||
}
|
||||
}
|
||||
|
||||
bitflags! {
|
||||
#[derive(Default, Debug, Clone, Copy, PartialEq, Eq)]
|
||||
struct ParserCtxFlags: u8 {
|
||||
const FOR_TARGET = 1 << 2;
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Copy, Clone)]
|
||||
enum FunctionKind {
|
||||
/// A lambda expression, e.g., `lambda x: x`
|
||||
@@ -1327,9 +1285,3 @@ impl RecoveryContext {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct SavedParserContext {
|
||||
flags: ParserCtxFlags,
|
||||
bomb: DebugDropBomb,
|
||||
}
|
||||
|
||||
@@ -6,6 +6,8 @@ use crate::parser::{recovery, Parser, RecoveryContextKind, SequenceMatchPatternP
|
||||
use crate::token_set::TokenSet;
|
||||
use crate::{ParseErrorType, Tok, TokenKind};
|
||||
|
||||
use super::expression::ExpressionContext;
|
||||
|
||||
/// The set of tokens that can start a literal pattern.
|
||||
const LITERAL_PATTERN_START_SET: TokenSet = TokenSet::new([
|
||||
TokenKind::None,
|
||||
@@ -483,7 +485,7 @@ impl<'src> Parser<'src> {
|
||||
TokenKind::Int | TokenKind::Float | TokenKind::Complex
|
||||
) =>
|
||||
{
|
||||
let unary_expr = self.parse_unary_expression();
|
||||
let unary_expr = self.parse_unary_expression(ExpressionContext::default());
|
||||
|
||||
if unary_expr.op.is_u_add() {
|
||||
self.add_error(
|
||||
|
||||
@@ -11,13 +11,12 @@ use ruff_text_size::{Ranged, TextRange, TextSize};
|
||||
use crate::parser::expression::{GeneratorExpressionInParentheses, ParsedExpr, EXPR_SET};
|
||||
use crate::parser::progress::ParserProgress;
|
||||
use crate::parser::{
|
||||
helpers, FunctionKind, Parser, ParserCtxFlags, RecoveryContext, RecoveryContextKind,
|
||||
WithItemKind,
|
||||
helpers, FunctionKind, Parser, RecoveryContext, RecoveryContextKind, WithItemKind,
|
||||
};
|
||||
use crate::token_set::TokenSet;
|
||||
use crate::{Mode, ParseErrorType, Tok, TokenKind};
|
||||
|
||||
use super::expression::{AllowNamedExpression, AllowStarredExpression, Precedence};
|
||||
use super::expression::{ExpressionContext, OperatorPrecedence, StarredExpressionPrecedence};
|
||||
use super::Parenthesized;
|
||||
|
||||
/// Tokens that represent compound statements.
|
||||
@@ -261,8 +260,11 @@ impl<'src> Parser<'src> {
|
||||
let start = self.node_start();
|
||||
|
||||
// simple_stmt: `... | yield_stmt | star_expressions | ...`
|
||||
let parsed_expr =
|
||||
self.parse_yield_expression_or_else(Parser::parse_star_expression_list);
|
||||
let parsed_expr = self.parse_expression_list(
|
||||
ExpressionContext::default()
|
||||
.with_yield_expression_allowed()
|
||||
.with_starred_expression_allowed(StarredExpressionPrecedence::BitwiseOr),
|
||||
);
|
||||
|
||||
if self.at(TokenKind::Equal) {
|
||||
Stmt::Assign(self.parse_assign_statement(parsed_expr, start))
|
||||
@@ -309,8 +311,10 @@ impl<'src> Parser<'src> {
|
||||
|parser| {
|
||||
// Allow starred expression to raise a better error message for
|
||||
// an invalid delete target later.
|
||||
let mut target =
|
||||
parser.parse_conditional_expression_or_higher(AllowStarredExpression::Yes);
|
||||
let mut target = parser.parse_conditional_expression_or_higher(
|
||||
ExpressionContext::default()
|
||||
.with_starred_expression_allowed(StarredExpressionPrecedence::Conditional),
|
||||
);
|
||||
helpers::set_expr_ctx(&mut target.expr, ExprContext::Del);
|
||||
|
||||
// test_err invalid_del_target
|
||||
@@ -356,9 +360,15 @@ impl<'src> Parser<'src> {
|
||||
// return yield from x
|
||||
// return x := 1
|
||||
// return *x and y
|
||||
let value = self
|
||||
.at_expr()
|
||||
.then(|| Box::new(self.parse_star_expression_list().expr));
|
||||
let value = self.at_expr().then(|| {
|
||||
Box::new(
|
||||
self.parse_expression_list(
|
||||
ExpressionContext::default()
|
||||
.with_starred_expression_allowed(StarredExpressionPrecedence::BitwiseOr),
|
||||
)
|
||||
.expr,
|
||||
)
|
||||
});
|
||||
|
||||
ast::StmtReturn {
|
||||
range: self.node_range(start),
|
||||
@@ -384,7 +394,7 @@ impl<'src> Parser<'src> {
|
||||
// raise *x
|
||||
// raise yield x
|
||||
// raise x := 1
|
||||
let exc = self.parse_expression_list(AllowStarredExpression::No);
|
||||
let exc = self.parse_expression_list(ExpressionContext::default());
|
||||
|
||||
if let Some(ast::ExprTuple {
|
||||
parenthesized: false,
|
||||
@@ -406,7 +416,7 @@ impl<'src> Parser<'src> {
|
||||
// raise x from *y
|
||||
// raise x from yield y
|
||||
// raise x from y := 1
|
||||
let cause = self.parse_expression_list(AllowStarredExpression::No);
|
||||
let cause = self.parse_expression_list(ExpressionContext::default());
|
||||
|
||||
if let Some(ast::ExprTuple {
|
||||
parenthesized: false,
|
||||
@@ -714,7 +724,7 @@ impl<'src> Parser<'src> {
|
||||
// assert assert x
|
||||
// assert yield x
|
||||
// assert x := 1
|
||||
let test = self.parse_conditional_expression_or_higher(AllowStarredExpression::No);
|
||||
let test = self.parse_conditional_expression_or_higher(ExpressionContext::default());
|
||||
|
||||
let msg = if self.eat(TokenKind::Comma) {
|
||||
if self.at_expr() {
|
||||
@@ -724,7 +734,7 @@ impl<'src> Parser<'src> {
|
||||
// assert False, yield x
|
||||
// assert False, x := 1
|
||||
Some(Box::new(
|
||||
self.parse_conditional_expression_or_higher(AllowStarredExpression::No)
|
||||
self.parse_conditional_expression_or_higher(ExpressionContext::default())
|
||||
.expr,
|
||||
))
|
||||
} else {
|
||||
@@ -854,7 +864,7 @@ impl<'src> Parser<'src> {
|
||||
// type x = yield y
|
||||
// type x = yield from y
|
||||
// type x = x := 1
|
||||
let value = self.parse_conditional_expression_or_higher(AllowStarredExpression::No);
|
||||
let value = self.parse_conditional_expression_or_higher(ExpressionContext::default());
|
||||
|
||||
ast::StmtTypeAlias {
|
||||
name: Box::new(name),
|
||||
@@ -1014,15 +1024,18 @@ impl<'src> Parser<'src> {
|
||||
// x = *lambda x: x
|
||||
// x = x := 1
|
||||
|
||||
let mut value = self.parse_yield_expression_or_else(Parser::parse_star_expression_list);
|
||||
let context = ExpressionContext::default()
|
||||
.with_yield_expression_allowed()
|
||||
.with_starred_expression_allowed(StarredExpressionPrecedence::BitwiseOr);
|
||||
|
||||
let mut value = self.parse_expression_list(context);
|
||||
|
||||
if self.at(TokenKind::Equal) {
|
||||
// This path is only taken when there are more than one assignment targets.
|
||||
self.parse_list(RecoveryContextKind::AssignmentTargets, |parser| {
|
||||
parser.bump(TokenKind::Equal);
|
||||
|
||||
let mut parsed_expr =
|
||||
parser.parse_yield_expression_or_else(Parser::parse_star_expression_list);
|
||||
let mut parsed_expr = parser.parse_expression_list(context);
|
||||
|
||||
std::mem::swap(&mut value, &mut parsed_expr);
|
||||
|
||||
@@ -1089,10 +1102,12 @@ impl<'src> Parser<'src> {
|
||||
// x: yield from b = 1
|
||||
// x: y := int = 1
|
||||
|
||||
let context = ExpressionContext::default();
|
||||
|
||||
// test_err ann_assign_stmt_type_alias_annotation
|
||||
// a: type X = int
|
||||
// lambda: type X = int
|
||||
let annotation = self.parse_conditional_expression_or_higher(AllowStarredExpression::No);
|
||||
let annotation = self.parse_conditional_expression_or_higher(context);
|
||||
|
||||
let value = if self.eat(TokenKind::Equal) {
|
||||
if self.at_expr() {
|
||||
@@ -1101,8 +1116,14 @@ impl<'src> Parser<'src> {
|
||||
// x: Any = x := 1
|
||||
// x: list = [x, *a | b, *a or b]
|
||||
Some(Box::new(
|
||||
self.parse_yield_expression_or_else(Parser::parse_star_expression_list)
|
||||
.expr,
|
||||
self.parse_expression_list(
|
||||
ExpressionContext::default()
|
||||
.with_yield_expression_allowed()
|
||||
.with_starred_expression_allowed(
|
||||
StarredExpressionPrecedence::BitwiseOr,
|
||||
),
|
||||
)
|
||||
.expr,
|
||||
))
|
||||
} else {
|
||||
// test_err ann_assign_stmt_missing_rhs
|
||||
@@ -1170,7 +1191,11 @@ impl<'src> Parser<'src> {
|
||||
// x += *yield from x
|
||||
// x += *lambda x: x
|
||||
// x += y := 1
|
||||
let value = self.parse_yield_expression_or_else(Parser::parse_star_expression_list);
|
||||
let value = self.parse_expression_list(
|
||||
ExpressionContext::default()
|
||||
.with_yield_expression_allowed()
|
||||
.with_starred_expression_allowed(StarredExpressionPrecedence::BitwiseOr),
|
||||
);
|
||||
|
||||
ast::StmtAugAssign {
|
||||
target: Box::new(target.expr),
|
||||
@@ -1198,7 +1223,7 @@ impl<'src> Parser<'src> {
|
||||
|
||||
// test_err if_stmt_missing_test
|
||||
// if : ...
|
||||
let test = self.parse_named_expression_or_higher(AllowStarredExpression::No);
|
||||
let test = self.parse_named_expression_or_higher(ExpressionContext::default());
|
||||
|
||||
// test_err if_stmt_missing_colon
|
||||
// if x
|
||||
@@ -1253,7 +1278,7 @@ impl<'src> Parser<'src> {
|
||||
// elif yield x:
|
||||
// pass
|
||||
Some(
|
||||
self.parse_named_expression_or_higher(AllowStarredExpression::No)
|
||||
self.parse_named_expression_or_higher(ExpressionContext::default())
|
||||
.expr,
|
||||
)
|
||||
} else {
|
||||
@@ -1414,7 +1439,7 @@ impl<'src> Parser<'src> {
|
||||
// pass
|
||||
// except* *x:
|
||||
// pass
|
||||
let parsed_expr = self.parse_expression_list(AllowStarredExpression::No);
|
||||
let parsed_expr = self.parse_expression_list(ExpressionContext::default());
|
||||
if matches!(
|
||||
parsed_expr.expr,
|
||||
Expr::Tuple(ast::ExprTuple {
|
||||
@@ -1522,22 +1547,34 @@ impl<'src> Parser<'src> {
|
||||
fn parse_for_statement(&mut self, start: TextSize) -> ast::StmtFor {
|
||||
self.bump(TokenKind::For);
|
||||
|
||||
// This is to avoid the ambiguity of the `in` token which is used in
|
||||
// both the `for` statement and the comparison expression. For example:
|
||||
//
|
||||
// ```python
|
||||
// for x in y:
|
||||
// # ^^^^^^
|
||||
// # This is not a comparison expression
|
||||
// pass
|
||||
// ```
|
||||
let saved_context = self.set_ctx(ParserCtxFlags::FOR_TARGET);
|
||||
|
||||
// test_err for_stmt_missing_target
|
||||
// for in x: ...
|
||||
let mut target = self.parse_expression_list(AllowStarredExpression::Yes);
|
||||
|
||||
self.restore_ctx(ParserCtxFlags::FOR_TARGET, saved_context);
|
||||
// test_ok for_in_target_valid_expr
|
||||
// for d[x in y] in target: ...
|
||||
// for (x in y)[0] in iter: ...
|
||||
// for (x in y).attr in iter: ...
|
||||
|
||||
// test_err for_stmt_invalid_target_in_keyword
|
||||
// for d(x in y) in target: ...
|
||||
// for (x in y)() in iter: ...
|
||||
// for (x in y) in iter: ...
|
||||
// for (x in y, z) in iter: ...
|
||||
// for [x in y, z] in iter: ...
|
||||
// for {x in y, z} in iter: ...
|
||||
|
||||
// test_err for_stmt_invalid_target_binary_expr
|
||||
// for x not in y in z: ...
|
||||
// for x == y in z: ...
|
||||
// for x or y in z: ...
|
||||
// for -x in y: ...
|
||||
// for not x in y: ...
|
||||
// for x | y in z: ...
|
||||
let mut target = self.parse_expression_list(
|
||||
ExpressionContext::default()
|
||||
.with_starred_expression_allowed(StarredExpressionPrecedence::Conditional)
|
||||
.with_in_not_included(),
|
||||
);
|
||||
|
||||
helpers::set_expr_ctx(&mut target.expr, ExprContext::Store);
|
||||
|
||||
@@ -1547,6 +1584,7 @@ impl<'src> Parser<'src> {
|
||||
// for *x and y in z: ...
|
||||
// for *x | y in z: ...
|
||||
// for await x in z: ...
|
||||
// for yield x in y: ...
|
||||
// for [x, 1, y, *["a"]] in z: ...
|
||||
self.validate_assignment_target(&target.expr);
|
||||
|
||||
@@ -1563,7 +1601,10 @@ impl<'src> Parser<'src> {
|
||||
// for x in *a and b: ...
|
||||
// for x in yield a: ...
|
||||
// for target in x := 1: ...
|
||||
let iter = self.parse_star_expression_list();
|
||||
let iter = self.parse_expression_list(
|
||||
ExpressionContext::default()
|
||||
.with_starred_expression_allowed(StarredExpressionPrecedence::BitwiseOr),
|
||||
);
|
||||
|
||||
self.expect(TokenKind::Colon);
|
||||
|
||||
@@ -1607,7 +1648,7 @@ impl<'src> Parser<'src> {
|
||||
// while yield x: ...
|
||||
// while a, b: ...
|
||||
// while a := 1, b: ...
|
||||
let test = self.parse_named_expression_or_higher(AllowStarredExpression::No);
|
||||
let test = self.parse_named_expression_or_higher(ExpressionContext::default());
|
||||
|
||||
// test_err while_stmt_missing_colon
|
||||
// while (
|
||||
@@ -1689,7 +1730,7 @@ impl<'src> Parser<'src> {
|
||||
// def foo() -> *int: ...
|
||||
// def foo() -> (*int): ...
|
||||
// def foo() -> yield x: ...
|
||||
let returns = self.parse_expression_list(AllowStarredExpression::No);
|
||||
let returns = self.parse_expression_list(ExpressionContext::default());
|
||||
|
||||
if matches!(
|
||||
returns.expr,
|
||||
@@ -2162,9 +2203,10 @@ impl<'src> Parser<'src> {
|
||||
// with (a | b) << c | d: ...
|
||||
// # Postfix should still be parsed first
|
||||
// with (a)[0] + b * c: ...
|
||||
self.parse_expression_with_precedence_recursive(
|
||||
self.parse_binary_expression_or_higher_recursive(
|
||||
lhs.into(),
|
||||
Precedence::Initial,
|
||||
OperatorPrecedence::Initial,
|
||||
ExpressionContext::default(),
|
||||
start,
|
||||
)
|
||||
.expr
|
||||
@@ -2215,9 +2257,11 @@ impl<'src> Parser<'src> {
|
||||
//
|
||||
// Thus, we can conclude that the grammar used should be:
|
||||
// (yield_expr | star_named_expression)
|
||||
let parsed_expr = self.parse_yield_expression_or_else(|p| {
|
||||
p.parse_star_expression_or_higher(AllowNamedExpression::Yes)
|
||||
});
|
||||
let parsed_expr = self.parse_named_expression_or_higher(
|
||||
ExpressionContext::default()
|
||||
.with_yield_expression_allowed()
|
||||
.with_starred_expression_allowed(StarredExpressionPrecedence::BitwiseOr),
|
||||
);
|
||||
|
||||
if matches!(self.current_token_kind(), TokenKind::Async | TokenKind::For) {
|
||||
if parsed_expr.is_unparenthesized_starred_expr() {
|
||||
@@ -2279,7 +2323,7 @@ impl<'src> Parser<'src> {
|
||||
} else {
|
||||
// If it's not in an ambiguous state, then the grammar of the with item
|
||||
// should be used which is `expression`.
|
||||
self.parse_conditional_expression_or_higher(AllowStarredExpression::No)
|
||||
self.parse_conditional_expression_or_higher(ExpressionContext::default())
|
||||
};
|
||||
|
||||
let optional_vars = self
|
||||
@@ -2305,7 +2349,10 @@ impl<'src> Parser<'src> {
|
||||
fn parse_with_item_optional_vars(&mut self) -> ParsedExpr {
|
||||
self.bump(TokenKind::As);
|
||||
|
||||
let mut target = self.parse_conditional_expression_or_higher(AllowStarredExpression::Yes);
|
||||
let mut target = self.parse_conditional_expression_or_higher(
|
||||
ExpressionContext::default()
|
||||
.with_starred_expression_allowed(StarredExpressionPrecedence::Conditional),
|
||||
);
|
||||
|
||||
// This has the same semantics as an assignment target.
|
||||
self.validate_assignment_target(&target.expr);
|
||||
@@ -2336,7 +2383,10 @@ impl<'src> Parser<'src> {
|
||||
//
|
||||
// First try with `star_named_expression`, then if there's no comma,
|
||||
// we'll restrict it to `named_expression`.
|
||||
let subject = self.parse_star_expression_or_higher(AllowNamedExpression::Yes);
|
||||
let subject = self.parse_named_expression_or_higher(
|
||||
ExpressionContext::default()
|
||||
.with_starred_expression_allowed(StarredExpressionPrecedence::BitwiseOr),
|
||||
);
|
||||
|
||||
// test_ok match_stmt_subject_expr
|
||||
// match x := 1:
|
||||
@@ -2360,7 +2410,11 @@ impl<'src> Parser<'src> {
|
||||
let subject = if self.at(TokenKind::Comma) {
|
||||
let tuple =
|
||||
self.parse_tuple_expression(subject.expr, subject_start, Parenthesized::No, |p| {
|
||||
p.parse_star_expression_or_higher(AllowNamedExpression::Yes)
|
||||
p.parse_named_expression_or_higher(
|
||||
ExpressionContext::default().with_starred_expression_allowed(
|
||||
StarredExpressionPrecedence::BitwiseOr,
|
||||
),
|
||||
)
|
||||
});
|
||||
|
||||
Expr::Tuple(tuple).into()
|
||||
@@ -2470,7 +2524,7 @@ impl<'src> Parser<'src> {
|
||||
// match x:
|
||||
// case y if yield x: ...
|
||||
Some(Box::new(
|
||||
self.parse_named_expression_or_higher(AllowStarredExpression::No)
|
||||
self.parse_named_expression_or_higher(ExpressionContext::default())
|
||||
.expr,
|
||||
))
|
||||
} else {
|
||||
@@ -2588,7 +2642,7 @@ impl<'src> Parser<'src> {
|
||||
// @yield x
|
||||
// @yield from x
|
||||
// def foo(): ...
|
||||
let parsed_expr = self.parse_named_expression_or_higher(AllowStarredExpression::No);
|
||||
let parsed_expr = self.parse_named_expression_or_higher(ExpressionContext::default());
|
||||
|
||||
decorators.push(ast::Decorator {
|
||||
expression: parsed_expr.expr,
|
||||
@@ -2744,7 +2798,11 @@ impl<'src> Parser<'src> {
|
||||
// def foo(*args: *int or str): ...
|
||||
// def foo(*args: *yield x): ...
|
||||
// # def foo(*args: **int): ...
|
||||
self.parse_star_expression_or_higher(AllowNamedExpression::No)
|
||||
self.parse_conditional_expression_or_higher(
|
||||
ExpressionContext::default().with_starred_expression_allowed(
|
||||
StarredExpressionPrecedence::BitwiseOr,
|
||||
),
|
||||
)
|
||||
}
|
||||
AllowStarAnnotation::No => {
|
||||
// test_ok param_with_annotation
|
||||
@@ -2757,7 +2815,7 @@ impl<'src> Parser<'src> {
|
||||
// def foo(arg: *int): ...
|
||||
// def foo(arg: yield int): ...
|
||||
// def foo(arg: x := int): ...
|
||||
self.parse_conditional_expression_or_higher(AllowStarredExpression::No)
|
||||
self.parse_conditional_expression_or_higher(ExpressionContext::default())
|
||||
}
|
||||
};
|
||||
Some(Box::new(parsed_expr.expr))
|
||||
@@ -2810,7 +2868,7 @@ impl<'src> Parser<'src> {
|
||||
// def foo(x=(*int)): ...
|
||||
// def foo(x=yield y): ...
|
||||
Some(Box::new(
|
||||
self.parse_conditional_expression_or_higher(AllowStarredExpression::No)
|
||||
self.parse_conditional_expression_or_higher(ExpressionContext::default())
|
||||
.expr,
|
||||
))
|
||||
} else {
|
||||
@@ -3177,7 +3235,7 @@ impl<'src> Parser<'src> {
|
||||
// type X[T: yield from x] = int
|
||||
// type X[T: x := int] = int
|
||||
Some(Box::new(
|
||||
self.parse_conditional_expression_or_higher(AllowStarredExpression::No)
|
||||
self.parse_conditional_expression_or_higher(ExpressionContext::default())
|
||||
.expr,
|
||||
))
|
||||
} else {
|
||||
|
||||
@@ -715,31 +715,43 @@ impl TokenKind {
|
||||
)
|
||||
}
|
||||
|
||||
/// Returns `true` if the current token is a boolean operator.
|
||||
#[inline]
|
||||
pub const fn is_bool_operator(&self) -> bool {
|
||||
matches!(self, TokenKind::And | TokenKind::Or)
|
||||
self.as_bool_operator().is_some()
|
||||
}
|
||||
|
||||
/// Returns the [`BoolOp`] that corresponds to this token kind, if it is a boolean operator,
|
||||
/// otherwise return [None].
|
||||
#[inline]
|
||||
pub const fn as_bool_operator(&self) -> Option<BoolOp> {
|
||||
Some(match self {
|
||||
TokenKind::And => BoolOp::And,
|
||||
TokenKind::Or => BoolOp::Or,
|
||||
_ => return None,
|
||||
})
|
||||
}
|
||||
|
||||
/// Returns the [`Operator`] that corresponds to this token kind, if it is
|
||||
/// an augmented assignment operator, or [`None`] otherwise.
|
||||
#[inline]
|
||||
pub const fn as_augmented_assign_operator(&self) -> Option<Operator> {
|
||||
match self {
|
||||
TokenKind::PlusEqual => Some(Operator::Add),
|
||||
TokenKind::MinusEqual => Some(Operator::Sub),
|
||||
TokenKind::StarEqual => Some(Operator::Mult),
|
||||
TokenKind::AtEqual => Some(Operator::MatMult),
|
||||
TokenKind::DoubleStarEqual => Some(Operator::Pow),
|
||||
TokenKind::SlashEqual => Some(Operator::Div),
|
||||
TokenKind::DoubleSlashEqual => Some(Operator::FloorDiv),
|
||||
TokenKind::PercentEqual => Some(Operator::Mod),
|
||||
TokenKind::AmperEqual => Some(Operator::BitAnd),
|
||||
TokenKind::VbarEqual => Some(Operator::BitOr),
|
||||
TokenKind::CircumflexEqual => Some(Operator::BitXor),
|
||||
TokenKind::LeftShiftEqual => Some(Operator::LShift),
|
||||
TokenKind::RightShiftEqual => Some(Operator::RShift),
|
||||
_ => None,
|
||||
}
|
||||
Some(match self {
|
||||
TokenKind::PlusEqual => Operator::Add,
|
||||
TokenKind::MinusEqual => Operator::Sub,
|
||||
TokenKind::StarEqual => Operator::Mult,
|
||||
TokenKind::AtEqual => Operator::MatMult,
|
||||
TokenKind::DoubleStarEqual => Operator::Pow,
|
||||
TokenKind::SlashEqual => Operator::Div,
|
||||
TokenKind::DoubleSlashEqual => Operator::FloorDiv,
|
||||
TokenKind::PercentEqual => Operator::Mod,
|
||||
TokenKind::AmperEqual => Operator::BitAnd,
|
||||
TokenKind::VbarEqual => Operator::BitOr,
|
||||
TokenKind::CircumflexEqual => Operator::BitXor,
|
||||
TokenKind::LeftShiftEqual => Operator::LShift,
|
||||
TokenKind::RightShiftEqual => Operator::RShift,
|
||||
_ => return None,
|
||||
})
|
||||
}
|
||||
|
||||
pub const fn from_token(token: &Tok) -> Self {
|
||||
@@ -888,18 +900,6 @@ impl TryFrom<TokenKind> for Operator {
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<TokenKind> for BoolOp {
|
||||
type Error = ();
|
||||
|
||||
fn try_from(value: TokenKind) -> Result<Self, Self::Error> {
|
||||
Ok(match value {
|
||||
TokenKind::And => BoolOp::And,
|
||||
TokenKind::Or => BoolOp::Or,
|
||||
_ => return Err(()),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<&Tok> for UnaryOp {
|
||||
type Error = String;
|
||||
|
||||
@@ -922,6 +922,16 @@ impl TryFrom<TokenKind> for UnaryOp {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<BoolOp> for TokenKind {
|
||||
#[inline]
|
||||
fn from(op: BoolOp) -> Self {
|
||||
match op {
|
||||
BoolOp::And => TokenKind::And,
|
||||
BoolOp::Or => TokenKind::Or,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for TokenKind {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
let value = match self {
|
||||
|
||||
@@ -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,
|
||||
},
|
||||
),
|
||||
},
|
||||
Reference in New Issue
Block a user