mirror of
https://github.com/astral-sh/ruff.git
synced 2025-08-03 02:13:08 +00:00
[syntax-errors] Unparenthesized assignment expressions in sets and indexes (#16404)
## Summary This PR detects unparenthesized assignment expressions used in set literals and comprehensions and in sequence indexes. The link to the release notes in https://github.com/astral-sh/ruff/issues/6591 just has this entry: > * Assignment expressions can now be used unparenthesized within set literals and set comprehensions, as well as in sequence indexes (but not slices). with no other information, so hopefully the test cases I came up with cover all of the changes. I also tested these out in the Python REPL and they actually worked in Python 3.9 too. I'm guessing this may be another case that was "formally made part of the language spec in Python 3.10, but usable -- and commonly used -- in Python >=3.9" as @AlexWaygood added to the body of #6591 for context managers. So we may want to change the version cutoff, but I've gone along with the release notes for now. ## Test Plan New inline parser tests and linter CLI tests.
This commit is contained in:
parent
b9d7c36a23
commit
3a32e56445
20 changed files with 1220 additions and 9 deletions
|
@ -0,0 +1,4 @@
|
||||||
|
# even after 3.9, an unparenthesized named expression is not allowed in a slice
|
||||||
|
lst[x:=1:-1]
|
||||||
|
lst[1:x:=1]
|
||||||
|
lst[1:3:x:=1]
|
|
@ -0,0 +1,3 @@
|
||||||
|
# parse_options: {"target-version": "3.8"}
|
||||||
|
# before 3.9, only emit the parse error, not the unsupported syntax error
|
||||||
|
lst[x:=1:-1]
|
|
@ -0,0 +1,2 @@
|
||||||
|
# parse_options: {"target-version": "3.8"}
|
||||||
|
lst[x:=1]
|
|
@ -0,0 +1,2 @@
|
||||||
|
# parse_options: {"target-version": "3.8"}
|
||||||
|
{last := x for x in range(3)}
|
|
@ -0,0 +1,4 @@
|
||||||
|
# parse_options: {"target-version": "3.8"}
|
||||||
|
{x := 1, 2, 3}
|
||||||
|
{1, x := 2, 3}
|
||||||
|
{1, 2, x := 3}
|
|
@ -0,0 +1,2 @@
|
||||||
|
# parse_options: {"target-version": "3.8"}
|
||||||
|
lst[(x:=1)]
|
|
@ -0,0 +1,3 @@
|
||||||
|
# parse_options: {"target-version": "3.8"}
|
||||||
|
{(x := 1), 2, 3}
|
||||||
|
{(last := x) for x in range(3)}
|
|
@ -0,0 +1,2 @@
|
||||||
|
# parse_options: {"target-version": "3.9"}
|
||||||
|
lst[x:=1]
|
|
@ -0,0 +1,3 @@
|
||||||
|
# parse_options: {"target-version": "3.9"}
|
||||||
|
{x := 1, 2, 3}
|
||||||
|
{last := x for x in range(3)}
|
|
@ -452,11 +452,55 @@ pub enum StarTupleKind {
|
||||||
Yield,
|
Yield,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq, Eq, Hash, Clone, Copy)]
|
||||||
|
pub enum UnparenthesizedNamedExprKind {
|
||||||
|
SequenceIndex,
|
||||||
|
SetLiteral,
|
||||||
|
SetComprehension,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Eq, Hash, Clone, Copy)]
|
#[derive(Debug, PartialEq, Eq, Hash, Clone, Copy)]
|
||||||
pub enum UnsupportedSyntaxErrorKind {
|
pub enum UnsupportedSyntaxErrorKind {
|
||||||
Match,
|
Match,
|
||||||
Walrus,
|
Walrus,
|
||||||
ExceptStar,
|
ExceptStar,
|
||||||
|
/// Represents the use of an unparenthesized named expression (`:=`) in a set literal, set
|
||||||
|
/// comprehension, or sequence index before Python 3.10.
|
||||||
|
///
|
||||||
|
/// ## Examples
|
||||||
|
///
|
||||||
|
/// These are allowed on Python 3.10:
|
||||||
|
///
|
||||||
|
/// ```python
|
||||||
|
/// {x := 1, 2, 3} # set literal
|
||||||
|
/// {last := x for x in range(3)} # set comprehension
|
||||||
|
/// lst[x := 1] # sequence index
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// But on Python 3.9 the named expression needs to be parenthesized:
|
||||||
|
///
|
||||||
|
/// ```python
|
||||||
|
/// {(x := 1), 2, 3} # set literal
|
||||||
|
/// {(last := x) for x in range(3)} # set comprehension
|
||||||
|
/// lst[(x := 1)] # sequence index
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// However, unparenthesized named expressions are never allowed in slices:
|
||||||
|
///
|
||||||
|
/// ```python
|
||||||
|
/// lst[x:=1:-1] # syntax error
|
||||||
|
/// lst[1:x:=1] # syntax error
|
||||||
|
/// lst[1:3:x:=1] # syntax error
|
||||||
|
///
|
||||||
|
/// lst[(x:=1):-1] # ok
|
||||||
|
/// lst[1:(x:=1)] # ok
|
||||||
|
/// lst[1:3:(x:=1)] # ok
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// ## References
|
||||||
|
///
|
||||||
|
/// - [Python 3.10 Other Language Changes](https://docs.python.org/3/whatsnew/3.10.html#other-language-changes)
|
||||||
|
UnparenthesizedNamedExpr(UnparenthesizedNamedExprKind),
|
||||||
|
|
||||||
/// Represents the use of a parenthesized keyword argument name after Python 3.8.
|
/// Represents the use of a parenthesized keyword argument name after Python 3.8.
|
||||||
///
|
///
|
||||||
|
@ -706,6 +750,15 @@ impl Display for UnsupportedSyntaxError {
|
||||||
UnsupportedSyntaxErrorKind::Match => "Cannot use `match` statement",
|
UnsupportedSyntaxErrorKind::Match => "Cannot use `match` statement",
|
||||||
UnsupportedSyntaxErrorKind::Walrus => "Cannot use named assignment expression (`:=`)",
|
UnsupportedSyntaxErrorKind::Walrus => "Cannot use named assignment expression (`:=`)",
|
||||||
UnsupportedSyntaxErrorKind::ExceptStar => "Cannot use `except*`",
|
UnsupportedSyntaxErrorKind::ExceptStar => "Cannot use `except*`",
|
||||||
|
UnsupportedSyntaxErrorKind::UnparenthesizedNamedExpr(
|
||||||
|
UnparenthesizedNamedExprKind::SequenceIndex,
|
||||||
|
) => "Cannot use unparenthesized assignment expression in a sequence index",
|
||||||
|
UnsupportedSyntaxErrorKind::UnparenthesizedNamedExpr(
|
||||||
|
UnparenthesizedNamedExprKind::SetLiteral,
|
||||||
|
) => "Cannot use unparenthesized assignment expression as an element in a set literal",
|
||||||
|
UnsupportedSyntaxErrorKind::UnparenthesizedNamedExpr(
|
||||||
|
UnparenthesizedNamedExprKind::SetComprehension,
|
||||||
|
) => "Cannot use unparenthesized assignment expression as an element in a set comprehension",
|
||||||
UnsupportedSyntaxErrorKind::ParenthesizedKeywordArgumentName => {
|
UnsupportedSyntaxErrorKind::ParenthesizedKeywordArgumentName => {
|
||||||
"Cannot use parenthesized keyword argument name"
|
"Cannot use parenthesized keyword argument name"
|
||||||
}
|
}
|
||||||
|
@ -765,6 +818,9 @@ impl UnsupportedSyntaxErrorKind {
|
||||||
UnsupportedSyntaxErrorKind::Match => Change::Added(PythonVersion::PY310),
|
UnsupportedSyntaxErrorKind::Match => Change::Added(PythonVersion::PY310),
|
||||||
UnsupportedSyntaxErrorKind::Walrus => Change::Added(PythonVersion::PY38),
|
UnsupportedSyntaxErrorKind::Walrus => Change::Added(PythonVersion::PY38),
|
||||||
UnsupportedSyntaxErrorKind::ExceptStar => Change::Added(PythonVersion::PY311),
|
UnsupportedSyntaxErrorKind::ExceptStar => Change::Added(PythonVersion::PY311),
|
||||||
|
UnsupportedSyntaxErrorKind::UnparenthesizedNamedExpr(_) => {
|
||||||
|
Change::Added(PythonVersion::PY39)
|
||||||
|
}
|
||||||
UnsupportedSyntaxErrorKind::StarTuple(_) => Change::Added(PythonVersion::PY38),
|
UnsupportedSyntaxErrorKind::StarTuple(_) => Change::Added(PythonVersion::PY38),
|
||||||
UnsupportedSyntaxErrorKind::RelaxedDecorator => Change::Added(PythonVersion::PY39),
|
UnsupportedSyntaxErrorKind::RelaxedDecorator => Change::Added(PythonVersion::PY39),
|
||||||
UnsupportedSyntaxErrorKind::PositionalOnlyParameter => {
|
UnsupportedSyntaxErrorKind::PositionalOnlyParameter => {
|
||||||
|
|
|
@ -11,7 +11,7 @@ use ruff_python_ast::{
|
||||||
};
|
};
|
||||||
use ruff_text_size::{Ranged, TextLen, TextRange, TextSize};
|
use ruff_text_size::{Ranged, TextLen, TextRange, TextSize};
|
||||||
|
|
||||||
use crate::error::StarTupleKind;
|
use crate::error::{StarTupleKind, UnparenthesizedNamedExprKind};
|
||||||
use crate::parser::progress::ParserProgress;
|
use crate::parser::progress::ParserProgress;
|
||||||
use crate::parser::{helpers, FunctionKind, Parser};
|
use crate::parser::{helpers, FunctionKind, Parser};
|
||||||
use crate::string::{parse_fstring_literal_element, parse_string_literal, StringType};
|
use crate::string::{parse_fstring_literal_element, parse_string_literal, StringType};
|
||||||
|
@ -900,15 +900,48 @@ impl<'src> Parser<'src> {
|
||||||
const STEP_END_SET: TokenSet =
|
const STEP_END_SET: TokenSet =
|
||||||
TokenSet::new([TokenKind::Comma, TokenKind::Rsqb]).union(NEWLINE_EOF_SET);
|
TokenSet::new([TokenKind::Comma, TokenKind::Rsqb]).union(NEWLINE_EOF_SET);
|
||||||
|
|
||||||
|
// test_err named_expr_slice
|
||||||
|
// # even after 3.9, an unparenthesized named expression is not allowed in a slice
|
||||||
|
// lst[x:=1:-1]
|
||||||
|
// lst[1:x:=1]
|
||||||
|
// lst[1:3:x:=1]
|
||||||
|
|
||||||
|
// test_err named_expr_slice_parse_error
|
||||||
|
// # parse_options: {"target-version": "3.8"}
|
||||||
|
// # before 3.9, only emit the parse error, not the unsupported syntax error
|
||||||
|
// lst[x:=1:-1]
|
||||||
|
|
||||||
let start = self.node_start();
|
let start = self.node_start();
|
||||||
|
|
||||||
let lower = if self.at_expr() {
|
let lower = if self.at_expr() {
|
||||||
let lower =
|
let lower =
|
||||||
self.parse_named_expression_or_higher(ExpressionContext::starred_conditional());
|
self.parse_named_expression_or_higher(ExpressionContext::starred_conditional());
|
||||||
|
|
||||||
|
// This means we're in a subscript.
|
||||||
if self.at_ts(NEWLINE_EOF_SET.union([TokenKind::Rsqb, TokenKind::Comma].into())) {
|
if self.at_ts(NEWLINE_EOF_SET.union([TokenKind::Rsqb, TokenKind::Comma].into())) {
|
||||||
|
// test_ok parenthesized_named_expr_index_py38
|
||||||
|
// # parse_options: {"target-version": "3.8"}
|
||||||
|
// lst[(x:=1)]
|
||||||
|
|
||||||
|
// test_ok unparenthesized_named_expr_index_py39
|
||||||
|
// # parse_options: {"target-version": "3.9"}
|
||||||
|
// lst[x:=1]
|
||||||
|
|
||||||
|
// test_err unparenthesized_named_expr_index_py38
|
||||||
|
// # parse_options: {"target-version": "3.8"}
|
||||||
|
// lst[x:=1]
|
||||||
|
if lower.is_unparenthesized_named_expr() {
|
||||||
|
self.add_unsupported_syntax_error(
|
||||||
|
UnsupportedSyntaxErrorKind::UnparenthesizedNamedExpr(
|
||||||
|
UnparenthesizedNamedExprKind::SequenceIndex,
|
||||||
|
),
|
||||||
|
lower.range(),
|
||||||
|
);
|
||||||
|
}
|
||||||
return lower.expr;
|
return lower.expr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Now we know we're in a slice.
|
||||||
if !lower.is_parenthesized {
|
if !lower.is_parenthesized {
|
||||||
match lower.expr {
|
match lower.expr {
|
||||||
Expr::Starred(_) => {
|
Expr::Starred(_) => {
|
||||||
|
@ -1659,6 +1692,26 @@ impl<'src> Parser<'src> {
|
||||||
ParseErrorType::IterableUnpackingInComprehension,
|
ParseErrorType::IterableUnpackingInComprehension,
|
||||||
&key_or_element,
|
&key_or_element,
|
||||||
);
|
);
|
||||||
|
} else if key_or_element.is_unparenthesized_named_expr() {
|
||||||
|
// test_ok parenthesized_named_expr_py38
|
||||||
|
// # parse_options: {"target-version": "3.8"}
|
||||||
|
// {(x := 1), 2, 3}
|
||||||
|
// {(last := x) for x in range(3)}
|
||||||
|
|
||||||
|
// test_ok unparenthesized_named_expr_py39
|
||||||
|
// # parse_options: {"target-version": "3.9"}
|
||||||
|
// {x := 1, 2, 3}
|
||||||
|
// {last := x for x in range(3)}
|
||||||
|
|
||||||
|
// test_err unparenthesized_named_expr_set_comp_py38
|
||||||
|
// # parse_options: {"target-version": "3.8"}
|
||||||
|
// {last := x for x in range(3)}
|
||||||
|
self.add_unsupported_syntax_error(
|
||||||
|
UnsupportedSyntaxErrorKind::UnparenthesizedNamedExpr(
|
||||||
|
UnparenthesizedNamedExprKind::SetComprehension,
|
||||||
|
),
|
||||||
|
key_or_element.range(),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Expr::SetComp(self.parse_set_comprehension_expression(key_or_element.expr, start))
|
Expr::SetComp(self.parse_set_comprehension_expression(key_or_element.expr, start))
|
||||||
|
@ -1697,7 +1750,7 @@ impl<'src> Parser<'src> {
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => Expr::Set(self.parse_set_expression(key_or_element.expr, start)),
|
_ => Expr::Set(self.parse_set_expression(key_or_element, start)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1847,19 +1900,42 @@ impl<'src> Parser<'src> {
|
||||||
/// Parses a set expression.
|
/// Parses a set expression.
|
||||||
///
|
///
|
||||||
/// See: <https://docs.python.org/3/reference/expressions.html#set-displays>
|
/// See: <https://docs.python.org/3/reference/expressions.html#set-displays>
|
||||||
fn parse_set_expression(&mut self, first_element: Expr, start: TextSize) -> ast::ExprSet {
|
fn parse_set_expression(&mut self, first_element: ParsedExpr, start: TextSize) -> ast::ExprSet {
|
||||||
if !self.at_sequence_end() {
|
if !self.at_sequence_end() {
|
||||||
self.expect(TokenKind::Comma);
|
self.expect(TokenKind::Comma);
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut elts = vec![first_element];
|
// test_err unparenthesized_named_expr_set_literal_py38
|
||||||
|
// # parse_options: {"target-version": "3.8"}
|
||||||
|
// {x := 1, 2, 3}
|
||||||
|
// {1, x := 2, 3}
|
||||||
|
// {1, 2, x := 3}
|
||||||
|
|
||||||
|
if first_element.is_unparenthesized_named_expr() {
|
||||||
|
self.add_unsupported_syntax_error(
|
||||||
|
UnsupportedSyntaxErrorKind::UnparenthesizedNamedExpr(
|
||||||
|
UnparenthesizedNamedExprKind::SetLiteral,
|
||||||
|
),
|
||||||
|
first_element.range(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut elts = vec![first_element.expr];
|
||||||
|
|
||||||
self.parse_comma_separated_list(RecoveryContextKind::SetElements, |parser| {
|
self.parse_comma_separated_list(RecoveryContextKind::SetElements, |parser| {
|
||||||
elts.push(
|
let parsed_expr =
|
||||||
parser
|
parser.parse_named_expression_or_higher(ExpressionContext::starred_bitwise_or());
|
||||||
.parse_named_expression_or_higher(ExpressionContext::starred_bitwise_or())
|
|
||||||
.expr,
|
if parsed_expr.is_unparenthesized_named_expr() {
|
||||||
);
|
parser.add_unsupported_syntax_error(
|
||||||
|
UnsupportedSyntaxErrorKind::UnparenthesizedNamedExpr(
|
||||||
|
UnparenthesizedNamedExprKind::SetLiteral,
|
||||||
|
),
|
||||||
|
parsed_expr.range(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
elts.push(parsed_expr.expr);
|
||||||
});
|
});
|
||||||
|
|
||||||
self.expect(TokenKind::Rbrace);
|
self.expect(TokenKind::Rbrace);
|
||||||
|
@ -2410,6 +2486,11 @@ impl ParsedExpr {
|
||||||
pub(super) const fn is_unparenthesized_starred_expr(&self) -> bool {
|
pub(super) const fn is_unparenthesized_starred_expr(&self) -> bool {
|
||||||
!self.is_parenthesized && self.expr.is_starred_expr()
|
!self.is_parenthesized && self.expr.is_starred_expr()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub(super) const fn is_unparenthesized_named_expr(&self) -> bool {
|
||||||
|
!self.is_parenthesized && self.expr.is_named_expr()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<Expr> for ParsedExpr {
|
impl From<Expr> for ParsedExpr {
|
||||||
|
|
|
@ -0,0 +1,258 @@
|
||||||
|
---
|
||||||
|
source: crates/ruff_python_parser/tests/fixtures.rs
|
||||||
|
input_file: crates/ruff_python_parser/resources/inline/err/named_expr_slice.py
|
||||||
|
---
|
||||||
|
## AST
|
||||||
|
|
||||||
|
```
|
||||||
|
Module(
|
||||||
|
ModModule {
|
||||||
|
range: 0..119,
|
||||||
|
body: [
|
||||||
|
Expr(
|
||||||
|
StmtExpr {
|
||||||
|
range: 80..92,
|
||||||
|
value: Subscript(
|
||||||
|
ExprSubscript {
|
||||||
|
range: 80..92,
|
||||||
|
value: Name(
|
||||||
|
ExprName {
|
||||||
|
range: 80..83,
|
||||||
|
id: Name("lst"),
|
||||||
|
ctx: Load,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
slice: Slice(
|
||||||
|
ExprSlice {
|
||||||
|
range: 84..91,
|
||||||
|
lower: Some(
|
||||||
|
Named(
|
||||||
|
ExprNamed {
|
||||||
|
range: 84..88,
|
||||||
|
target: Name(
|
||||||
|
ExprName {
|
||||||
|
range: 84..85,
|
||||||
|
id: Name("x"),
|
||||||
|
ctx: Store,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
value: NumberLiteral(
|
||||||
|
ExprNumberLiteral {
|
||||||
|
range: 87..88,
|
||||||
|
value: Int(
|
||||||
|
1,
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
upper: Some(
|
||||||
|
UnaryOp(
|
||||||
|
ExprUnaryOp {
|
||||||
|
range: 89..91,
|
||||||
|
op: USub,
|
||||||
|
operand: NumberLiteral(
|
||||||
|
ExprNumberLiteral {
|
||||||
|
range: 90..91,
|
||||||
|
value: Int(
|
||||||
|
1,
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
step: None,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
ctx: Load,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
Expr(
|
||||||
|
StmtExpr {
|
||||||
|
range: 93..100,
|
||||||
|
value: Subscript(
|
||||||
|
ExprSubscript {
|
||||||
|
range: 93..100,
|
||||||
|
value: Name(
|
||||||
|
ExprName {
|
||||||
|
range: 93..96,
|
||||||
|
id: Name("lst"),
|
||||||
|
ctx: Load,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
slice: Slice(
|
||||||
|
ExprSlice {
|
||||||
|
range: 97..100,
|
||||||
|
lower: Some(
|
||||||
|
NumberLiteral(
|
||||||
|
ExprNumberLiteral {
|
||||||
|
range: 97..98,
|
||||||
|
value: Int(
|
||||||
|
1,
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
upper: Some(
|
||||||
|
Name(
|
||||||
|
ExprName {
|
||||||
|
range: 99..100,
|
||||||
|
id: Name("x"),
|
||||||
|
ctx: Load,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
step: None,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
ctx: Load,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
Expr(
|
||||||
|
StmtExpr {
|
||||||
|
range: 102..103,
|
||||||
|
value: NumberLiteral(
|
||||||
|
ExprNumberLiteral {
|
||||||
|
range: 102..103,
|
||||||
|
value: Int(
|
||||||
|
1,
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
Expr(
|
||||||
|
StmtExpr {
|
||||||
|
range: 105..114,
|
||||||
|
value: Subscript(
|
||||||
|
ExprSubscript {
|
||||||
|
range: 105..114,
|
||||||
|
value: Name(
|
||||||
|
ExprName {
|
||||||
|
range: 105..108,
|
||||||
|
id: Name("lst"),
|
||||||
|
ctx: Load,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
slice: Slice(
|
||||||
|
ExprSlice {
|
||||||
|
range: 109..114,
|
||||||
|
lower: Some(
|
||||||
|
NumberLiteral(
|
||||||
|
ExprNumberLiteral {
|
||||||
|
range: 109..110,
|
||||||
|
value: Int(
|
||||||
|
1,
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
upper: Some(
|
||||||
|
NumberLiteral(
|
||||||
|
ExprNumberLiteral {
|
||||||
|
range: 111..112,
|
||||||
|
value: Int(
|
||||||
|
3,
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
step: Some(
|
||||||
|
Name(
|
||||||
|
ExprName {
|
||||||
|
range: 113..114,
|
||||||
|
id: Name("x"),
|
||||||
|
ctx: Load,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
ctx: Load,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
Expr(
|
||||||
|
StmtExpr {
|
||||||
|
range: 116..117,
|
||||||
|
value: NumberLiteral(
|
||||||
|
ExprNumberLiteral {
|
||||||
|
range: 116..117,
|
||||||
|
value: Int(
|
||||||
|
1,
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
)
|
||||||
|
```
|
||||||
|
## Errors
|
||||||
|
|
||||||
|
|
|
||||||
|
1 | # even after 3.9, an unparenthesized named expression is not allowed in a slice
|
||||||
|
2 | lst[x:=1:-1]
|
||||||
|
| ^^^^ Syntax Error: Unparenthesized named expression cannot be used here
|
||||||
|
3 | lst[1:x:=1]
|
||||||
|
4 | lst[1:3:x:=1]
|
||||||
|
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
1 | # even after 3.9, an unparenthesized named expression is not allowed in a slice
|
||||||
|
2 | lst[x:=1:-1]
|
||||||
|
3 | lst[1:x:=1]
|
||||||
|
| ^^ Syntax Error: Expected ']', found ':='
|
||||||
|
4 | lst[1:3:x:=1]
|
||||||
|
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
1 | # even after 3.9, an unparenthesized named expression is not allowed in a slice
|
||||||
|
2 | lst[x:=1:-1]
|
||||||
|
3 | lst[1:x:=1]
|
||||||
|
| ^ Syntax Error: Expected a statement
|
||||||
|
4 | lst[1:3:x:=1]
|
||||||
|
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
1 | # even after 3.9, an unparenthesized named expression is not allowed in a slice
|
||||||
|
2 | lst[x:=1:-1]
|
||||||
|
3 | lst[1:x:=1]
|
||||||
|
| ^ Syntax Error: Expected a statement
|
||||||
|
4 | lst[1:3:x:=1]
|
||||||
|
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
2 | lst[x:=1:-1]
|
||||||
|
3 | lst[1:x:=1]
|
||||||
|
4 | lst[1:3:x:=1]
|
||||||
|
| ^^ Syntax Error: Expected ']', found ':='
|
||||||
|
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
2 | lst[x:=1:-1]
|
||||||
|
3 | lst[1:x:=1]
|
||||||
|
4 | lst[1:3:x:=1]
|
||||||
|
| ^ Syntax Error: Expected a statement
|
||||||
|
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
2 | lst[x:=1:-1]
|
||||||
|
3 | lst[1:x:=1]
|
||||||
|
4 | lst[1:3:x:=1]
|
||||||
|
| ^ Syntax Error: Expected a statement
|
||||||
|
|
|
|
@ -0,0 +1,85 @@
|
||||||
|
---
|
||||||
|
source: crates/ruff_python_parser/tests/fixtures.rs
|
||||||
|
input_file: crates/ruff_python_parser/resources/inline/err/named_expr_slice_parse_error.py
|
||||||
|
---
|
||||||
|
## AST
|
||||||
|
|
||||||
|
```
|
||||||
|
Module(
|
||||||
|
ModModule {
|
||||||
|
range: 0..130,
|
||||||
|
body: [
|
||||||
|
Expr(
|
||||||
|
StmtExpr {
|
||||||
|
range: 117..129,
|
||||||
|
value: Subscript(
|
||||||
|
ExprSubscript {
|
||||||
|
range: 117..129,
|
||||||
|
value: Name(
|
||||||
|
ExprName {
|
||||||
|
range: 117..120,
|
||||||
|
id: Name("lst"),
|
||||||
|
ctx: Load,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
slice: Slice(
|
||||||
|
ExprSlice {
|
||||||
|
range: 121..128,
|
||||||
|
lower: Some(
|
||||||
|
Named(
|
||||||
|
ExprNamed {
|
||||||
|
range: 121..125,
|
||||||
|
target: Name(
|
||||||
|
ExprName {
|
||||||
|
range: 121..122,
|
||||||
|
id: Name("x"),
|
||||||
|
ctx: Store,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
value: NumberLiteral(
|
||||||
|
ExprNumberLiteral {
|
||||||
|
range: 124..125,
|
||||||
|
value: Int(
|
||||||
|
1,
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
upper: Some(
|
||||||
|
UnaryOp(
|
||||||
|
ExprUnaryOp {
|
||||||
|
range: 126..128,
|
||||||
|
op: USub,
|
||||||
|
operand: NumberLiteral(
|
||||||
|
ExprNumberLiteral {
|
||||||
|
range: 127..128,
|
||||||
|
value: Int(
|
||||||
|
1,
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
step: None,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
ctx: Load,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
)
|
||||||
|
```
|
||||||
|
## Errors
|
||||||
|
|
||||||
|
|
|
||||||
|
1 | # parse_options: {"target-version": "3.8"}
|
||||||
|
2 | # before 3.9, only emit the parse error, not the unsupported syntax error
|
||||||
|
3 | lst[x:=1:-1]
|
||||||
|
| ^^^^ Syntax Error: Unparenthesized named expression cannot be used here
|
||||||
|
|
|
|
@ -0,0 +1,60 @@
|
||||||
|
---
|
||||||
|
source: crates/ruff_python_parser/tests/fixtures.rs
|
||||||
|
input_file: crates/ruff_python_parser/resources/inline/err/unparenthesized_named_expr_index_py38.py
|
||||||
|
---
|
||||||
|
## AST
|
||||||
|
|
||||||
|
```
|
||||||
|
Module(
|
||||||
|
ModModule {
|
||||||
|
range: 0..53,
|
||||||
|
body: [
|
||||||
|
Expr(
|
||||||
|
StmtExpr {
|
||||||
|
range: 43..52,
|
||||||
|
value: Subscript(
|
||||||
|
ExprSubscript {
|
||||||
|
range: 43..52,
|
||||||
|
value: Name(
|
||||||
|
ExprName {
|
||||||
|
range: 43..46,
|
||||||
|
id: Name("lst"),
|
||||||
|
ctx: Load,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
slice: Named(
|
||||||
|
ExprNamed {
|
||||||
|
range: 47..51,
|
||||||
|
target: Name(
|
||||||
|
ExprName {
|
||||||
|
range: 47..48,
|
||||||
|
id: Name("x"),
|
||||||
|
ctx: Store,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
value: NumberLiteral(
|
||||||
|
ExprNumberLiteral {
|
||||||
|
range: 50..51,
|
||||||
|
value: Int(
|
||||||
|
1,
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
ctx: Load,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
)
|
||||||
|
```
|
||||||
|
## Unsupported Syntax Errors
|
||||||
|
|
||||||
|
|
|
||||||
|
1 | # parse_options: {"target-version": "3.8"}
|
||||||
|
2 | lst[x:=1]
|
||||||
|
| ^^^^ Syntax Error: Cannot use unparenthesized assignment expression in a sequence index on Python 3.8 (syntax was added in Python 3.9)
|
||||||
|
|
|
|
@ -0,0 +1,91 @@
|
||||||
|
---
|
||||||
|
source: crates/ruff_python_parser/tests/fixtures.rs
|
||||||
|
input_file: crates/ruff_python_parser/resources/inline/err/unparenthesized_named_expr_set_comp_py38.py
|
||||||
|
---
|
||||||
|
## AST
|
||||||
|
|
||||||
|
```
|
||||||
|
Module(
|
||||||
|
ModModule {
|
||||||
|
range: 0..73,
|
||||||
|
body: [
|
||||||
|
Expr(
|
||||||
|
StmtExpr {
|
||||||
|
range: 43..72,
|
||||||
|
value: SetComp(
|
||||||
|
ExprSetComp {
|
||||||
|
range: 43..72,
|
||||||
|
elt: Named(
|
||||||
|
ExprNamed {
|
||||||
|
range: 44..53,
|
||||||
|
target: Name(
|
||||||
|
ExprName {
|
||||||
|
range: 44..48,
|
||||||
|
id: Name("last"),
|
||||||
|
ctx: Store,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
value: Name(
|
||||||
|
ExprName {
|
||||||
|
range: 52..53,
|
||||||
|
id: Name("x"),
|
||||||
|
ctx: Load,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
generators: [
|
||||||
|
Comprehension {
|
||||||
|
range: 54..71,
|
||||||
|
target: Name(
|
||||||
|
ExprName {
|
||||||
|
range: 58..59,
|
||||||
|
id: Name("x"),
|
||||||
|
ctx: Store,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
iter: Call(
|
||||||
|
ExprCall {
|
||||||
|
range: 63..71,
|
||||||
|
func: Name(
|
||||||
|
ExprName {
|
||||||
|
range: 63..68,
|
||||||
|
id: Name("range"),
|
||||||
|
ctx: Load,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
arguments: Arguments {
|
||||||
|
range: 68..71,
|
||||||
|
args: [
|
||||||
|
NumberLiteral(
|
||||||
|
ExprNumberLiteral {
|
||||||
|
range: 69..70,
|
||||||
|
value: Int(
|
||||||
|
3,
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
keywords: [],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
ifs: [],
|
||||||
|
is_async: false,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
)
|
||||||
|
```
|
||||||
|
## Unsupported Syntax Errors
|
||||||
|
|
||||||
|
|
|
||||||
|
1 | # parse_options: {"target-version": "3.8"}
|
||||||
|
2 | {last := x for x in range(3)}
|
||||||
|
| ^^^^^^^^^ Syntax Error: Cannot use unparenthesized assignment expression as an element in a set comprehension on Python 3.8 (syntax was added in Python 3.9)
|
||||||
|
|
|
|
@ -0,0 +1,185 @@
|
||||||
|
---
|
||||||
|
source: crates/ruff_python_parser/tests/fixtures.rs
|
||||||
|
input_file: crates/ruff_python_parser/resources/inline/err/unparenthesized_named_expr_set_literal_py38.py
|
||||||
|
---
|
||||||
|
## AST
|
||||||
|
|
||||||
|
```
|
||||||
|
Module(
|
||||||
|
ModModule {
|
||||||
|
range: 0..88,
|
||||||
|
body: [
|
||||||
|
Expr(
|
||||||
|
StmtExpr {
|
||||||
|
range: 43..57,
|
||||||
|
value: Set(
|
||||||
|
ExprSet {
|
||||||
|
range: 43..57,
|
||||||
|
elts: [
|
||||||
|
Named(
|
||||||
|
ExprNamed {
|
||||||
|
range: 44..50,
|
||||||
|
target: Name(
|
||||||
|
ExprName {
|
||||||
|
range: 44..45,
|
||||||
|
id: Name("x"),
|
||||||
|
ctx: Store,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
value: NumberLiteral(
|
||||||
|
ExprNumberLiteral {
|
||||||
|
range: 49..50,
|
||||||
|
value: Int(
|
||||||
|
1,
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
NumberLiteral(
|
||||||
|
ExprNumberLiteral {
|
||||||
|
range: 52..53,
|
||||||
|
value: Int(
|
||||||
|
2,
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
NumberLiteral(
|
||||||
|
ExprNumberLiteral {
|
||||||
|
range: 55..56,
|
||||||
|
value: Int(
|
||||||
|
3,
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
Expr(
|
||||||
|
StmtExpr {
|
||||||
|
range: 58..72,
|
||||||
|
value: Set(
|
||||||
|
ExprSet {
|
||||||
|
range: 58..72,
|
||||||
|
elts: [
|
||||||
|
NumberLiteral(
|
||||||
|
ExprNumberLiteral {
|
||||||
|
range: 59..60,
|
||||||
|
value: Int(
|
||||||
|
1,
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
Named(
|
||||||
|
ExprNamed {
|
||||||
|
range: 62..68,
|
||||||
|
target: Name(
|
||||||
|
ExprName {
|
||||||
|
range: 62..63,
|
||||||
|
id: Name("x"),
|
||||||
|
ctx: Store,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
value: NumberLiteral(
|
||||||
|
ExprNumberLiteral {
|
||||||
|
range: 67..68,
|
||||||
|
value: Int(
|
||||||
|
2,
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
NumberLiteral(
|
||||||
|
ExprNumberLiteral {
|
||||||
|
range: 70..71,
|
||||||
|
value: Int(
|
||||||
|
3,
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
Expr(
|
||||||
|
StmtExpr {
|
||||||
|
range: 73..87,
|
||||||
|
value: Set(
|
||||||
|
ExprSet {
|
||||||
|
range: 73..87,
|
||||||
|
elts: [
|
||||||
|
NumberLiteral(
|
||||||
|
ExprNumberLiteral {
|
||||||
|
range: 74..75,
|
||||||
|
value: Int(
|
||||||
|
1,
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
NumberLiteral(
|
||||||
|
ExprNumberLiteral {
|
||||||
|
range: 77..78,
|
||||||
|
value: Int(
|
||||||
|
2,
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
Named(
|
||||||
|
ExprNamed {
|
||||||
|
range: 80..86,
|
||||||
|
target: Name(
|
||||||
|
ExprName {
|
||||||
|
range: 80..81,
|
||||||
|
id: Name("x"),
|
||||||
|
ctx: Store,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
value: NumberLiteral(
|
||||||
|
ExprNumberLiteral {
|
||||||
|
range: 85..86,
|
||||||
|
value: Int(
|
||||||
|
3,
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
)
|
||||||
|
```
|
||||||
|
## Unsupported Syntax Errors
|
||||||
|
|
||||||
|
|
|
||||||
|
1 | # parse_options: {"target-version": "3.8"}
|
||||||
|
2 | {x := 1, 2, 3}
|
||||||
|
| ^^^^^^ Syntax Error: Cannot use unparenthesized assignment expression as an element in a set literal on Python 3.8 (syntax was added in Python 3.9)
|
||||||
|
3 | {1, x := 2, 3}
|
||||||
|
4 | {1, 2, x := 3}
|
||||||
|
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
1 | # parse_options: {"target-version": "3.8"}
|
||||||
|
2 | {x := 1, 2, 3}
|
||||||
|
3 | {1, x := 2, 3}
|
||||||
|
| ^^^^^^ Syntax Error: Cannot use unparenthesized assignment expression as an element in a set literal on Python 3.8 (syntax was added in Python 3.9)
|
||||||
|
4 | {1, 2, x := 3}
|
||||||
|
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
2 | {x := 1, 2, 3}
|
||||||
|
3 | {1, x := 2, 3}
|
||||||
|
4 | {1, 2, x := 3}
|
||||||
|
| ^^^^^^ Syntax Error: Cannot use unparenthesized assignment expression as an element in a set literal on Python 3.8 (syntax was added in Python 3.9)
|
||||||
|
|
|
|
@ -0,0 +1,53 @@
|
||||||
|
---
|
||||||
|
source: crates/ruff_python_parser/tests/fixtures.rs
|
||||||
|
input_file: crates/ruff_python_parser/resources/inline/ok/parenthesized_named_expr_index_py38.py
|
||||||
|
---
|
||||||
|
## AST
|
||||||
|
|
||||||
|
```
|
||||||
|
Module(
|
||||||
|
ModModule {
|
||||||
|
range: 0..55,
|
||||||
|
body: [
|
||||||
|
Expr(
|
||||||
|
StmtExpr {
|
||||||
|
range: 43..54,
|
||||||
|
value: Subscript(
|
||||||
|
ExprSubscript {
|
||||||
|
range: 43..54,
|
||||||
|
value: Name(
|
||||||
|
ExprName {
|
||||||
|
range: 43..46,
|
||||||
|
id: Name("lst"),
|
||||||
|
ctx: Load,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
slice: Named(
|
||||||
|
ExprNamed {
|
||||||
|
range: 48..52,
|
||||||
|
target: Name(
|
||||||
|
ExprName {
|
||||||
|
range: 48..49,
|
||||||
|
id: Name("x"),
|
||||||
|
ctx: Store,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
value: NumberLiteral(
|
||||||
|
ExprNumberLiteral {
|
||||||
|
range: 51..52,
|
||||||
|
value: Int(
|
||||||
|
1,
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
ctx: Load,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
)
|
||||||
|
```
|
|
@ -0,0 +1,132 @@
|
||||||
|
---
|
||||||
|
source: crates/ruff_python_parser/tests/fixtures.rs
|
||||||
|
input_file: crates/ruff_python_parser/resources/inline/ok/parenthesized_named_expr_py38.py
|
||||||
|
---
|
||||||
|
## AST
|
||||||
|
|
||||||
|
```
|
||||||
|
Module(
|
||||||
|
ModModule {
|
||||||
|
range: 0..92,
|
||||||
|
body: [
|
||||||
|
Expr(
|
||||||
|
StmtExpr {
|
||||||
|
range: 43..59,
|
||||||
|
value: Set(
|
||||||
|
ExprSet {
|
||||||
|
range: 43..59,
|
||||||
|
elts: [
|
||||||
|
Named(
|
||||||
|
ExprNamed {
|
||||||
|
range: 45..51,
|
||||||
|
target: Name(
|
||||||
|
ExprName {
|
||||||
|
range: 45..46,
|
||||||
|
id: Name("x"),
|
||||||
|
ctx: Store,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
value: NumberLiteral(
|
||||||
|
ExprNumberLiteral {
|
||||||
|
range: 50..51,
|
||||||
|
value: Int(
|
||||||
|
1,
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
NumberLiteral(
|
||||||
|
ExprNumberLiteral {
|
||||||
|
range: 54..55,
|
||||||
|
value: Int(
|
||||||
|
2,
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
NumberLiteral(
|
||||||
|
ExprNumberLiteral {
|
||||||
|
range: 57..58,
|
||||||
|
value: Int(
|
||||||
|
3,
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
Expr(
|
||||||
|
StmtExpr {
|
||||||
|
range: 60..91,
|
||||||
|
value: SetComp(
|
||||||
|
ExprSetComp {
|
||||||
|
range: 60..91,
|
||||||
|
elt: Named(
|
||||||
|
ExprNamed {
|
||||||
|
range: 62..71,
|
||||||
|
target: Name(
|
||||||
|
ExprName {
|
||||||
|
range: 62..66,
|
||||||
|
id: Name("last"),
|
||||||
|
ctx: Store,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
value: Name(
|
||||||
|
ExprName {
|
||||||
|
range: 70..71,
|
||||||
|
id: Name("x"),
|
||||||
|
ctx: Load,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
generators: [
|
||||||
|
Comprehension {
|
||||||
|
range: 73..90,
|
||||||
|
target: Name(
|
||||||
|
ExprName {
|
||||||
|
range: 77..78,
|
||||||
|
id: Name("x"),
|
||||||
|
ctx: Store,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
iter: Call(
|
||||||
|
ExprCall {
|
||||||
|
range: 82..90,
|
||||||
|
func: Name(
|
||||||
|
ExprName {
|
||||||
|
range: 82..87,
|
||||||
|
id: Name("range"),
|
||||||
|
ctx: Load,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
arguments: Arguments {
|
||||||
|
range: 87..90,
|
||||||
|
args: [
|
||||||
|
NumberLiteral(
|
||||||
|
ExprNumberLiteral {
|
||||||
|
range: 88..89,
|
||||||
|
value: Int(
|
||||||
|
3,
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
keywords: [],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
ifs: [],
|
||||||
|
is_async: false,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
)
|
||||||
|
```
|
|
@ -0,0 +1,53 @@
|
||||||
|
---
|
||||||
|
source: crates/ruff_python_parser/tests/fixtures.rs
|
||||||
|
input_file: crates/ruff_python_parser/resources/inline/ok/unparenthesized_named_expr_index_py39.py
|
||||||
|
---
|
||||||
|
## AST
|
||||||
|
|
||||||
|
```
|
||||||
|
Module(
|
||||||
|
ModModule {
|
||||||
|
range: 0..53,
|
||||||
|
body: [
|
||||||
|
Expr(
|
||||||
|
StmtExpr {
|
||||||
|
range: 43..52,
|
||||||
|
value: Subscript(
|
||||||
|
ExprSubscript {
|
||||||
|
range: 43..52,
|
||||||
|
value: Name(
|
||||||
|
ExprName {
|
||||||
|
range: 43..46,
|
||||||
|
id: Name("lst"),
|
||||||
|
ctx: Load,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
slice: Named(
|
||||||
|
ExprNamed {
|
||||||
|
range: 47..51,
|
||||||
|
target: Name(
|
||||||
|
ExprName {
|
||||||
|
range: 47..48,
|
||||||
|
id: Name("x"),
|
||||||
|
ctx: Store,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
value: NumberLiteral(
|
||||||
|
ExprNumberLiteral {
|
||||||
|
range: 50..51,
|
||||||
|
value: Int(
|
||||||
|
1,
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
ctx: Load,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
)
|
||||||
|
```
|
|
@ -0,0 +1,132 @@
|
||||||
|
---
|
||||||
|
source: crates/ruff_python_parser/tests/fixtures.rs
|
||||||
|
input_file: crates/ruff_python_parser/resources/inline/ok/unparenthesized_named_expr_py39.py
|
||||||
|
---
|
||||||
|
## AST
|
||||||
|
|
||||||
|
```
|
||||||
|
Module(
|
||||||
|
ModModule {
|
||||||
|
range: 0..88,
|
||||||
|
body: [
|
||||||
|
Expr(
|
||||||
|
StmtExpr {
|
||||||
|
range: 43..57,
|
||||||
|
value: Set(
|
||||||
|
ExprSet {
|
||||||
|
range: 43..57,
|
||||||
|
elts: [
|
||||||
|
Named(
|
||||||
|
ExprNamed {
|
||||||
|
range: 44..50,
|
||||||
|
target: Name(
|
||||||
|
ExprName {
|
||||||
|
range: 44..45,
|
||||||
|
id: Name("x"),
|
||||||
|
ctx: Store,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
value: NumberLiteral(
|
||||||
|
ExprNumberLiteral {
|
||||||
|
range: 49..50,
|
||||||
|
value: Int(
|
||||||
|
1,
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
NumberLiteral(
|
||||||
|
ExprNumberLiteral {
|
||||||
|
range: 52..53,
|
||||||
|
value: Int(
|
||||||
|
2,
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
NumberLiteral(
|
||||||
|
ExprNumberLiteral {
|
||||||
|
range: 55..56,
|
||||||
|
value: Int(
|
||||||
|
3,
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
Expr(
|
||||||
|
StmtExpr {
|
||||||
|
range: 58..87,
|
||||||
|
value: SetComp(
|
||||||
|
ExprSetComp {
|
||||||
|
range: 58..87,
|
||||||
|
elt: Named(
|
||||||
|
ExprNamed {
|
||||||
|
range: 59..68,
|
||||||
|
target: Name(
|
||||||
|
ExprName {
|
||||||
|
range: 59..63,
|
||||||
|
id: Name("last"),
|
||||||
|
ctx: Store,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
value: Name(
|
||||||
|
ExprName {
|
||||||
|
range: 67..68,
|
||||||
|
id: Name("x"),
|
||||||
|
ctx: Load,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
generators: [
|
||||||
|
Comprehension {
|
||||||
|
range: 69..86,
|
||||||
|
target: Name(
|
||||||
|
ExprName {
|
||||||
|
range: 73..74,
|
||||||
|
id: Name("x"),
|
||||||
|
ctx: Store,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
iter: Call(
|
||||||
|
ExprCall {
|
||||||
|
range: 78..86,
|
||||||
|
func: Name(
|
||||||
|
ExprName {
|
||||||
|
range: 78..83,
|
||||||
|
id: Name("range"),
|
||||||
|
ctx: Load,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
arguments: Arguments {
|
||||||
|
range: 83..86,
|
||||||
|
args: [
|
||||||
|
NumberLiteral(
|
||||||
|
ExprNumberLiteral {
|
||||||
|
range: 84..85,
|
||||||
|
value: Int(
|
||||||
|
3,
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
keywords: [],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
ifs: [],
|
||||||
|
is_async: false,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
)
|
||||||
|
```
|
Loading…
Add table
Add a link
Reference in a new issue