mirror of https://github.com/astral-sh/ruff
[syntax-errors] PEP 701 f-strings before Python 3.12 (#16543)
## Summary This PR detects the use of PEP 701 f-strings before 3.12. This one sounded difficult and ended up being pretty easy, so I think there's a good chance I've over-simplified things. However, from experimenting in the Python REPL and checking with [pyright], I think this is correct. pyright actually doesn't even flag the comment case, but Python does. I also checked pyright's implementation for [quotes](98dc4469cc/packages/pyright-internal/src/analyzer/checker.ts (L1379-L1398)) and [escapes](98dc4469cc/packages/pyright-internal/src/analyzer/checker.ts (L1365-L1377)) and think I've approximated how they do it. Python's error messages also point to the simple approach of these characters simply not being allowed: ```pycon Python 3.11.11 (main, Feb 12 2025, 14:51:05) [Clang 19.1.6 ] on linux Type "help", "copyright", "credits" or "license" for more information. >>> f'''multiline { ... expression # comment ... }''' File "<stdin>", line 3 }''' ^ SyntaxError: f-string expression part cannot include '#' >>> f'''{not a line \ ... continuation}''' File "<stdin>", line 2 continuation}''' ^ SyntaxError: f-string expression part cannot include a backslash >>> f'hello {'world'}' File "<stdin>", line 1 f'hello {'world'}' ^^^^^ SyntaxError: f-string: expecting '}' ``` And since escapes aren't allowed, I don't think there are any tricky cases where nested quotes or comments can sneak in. It's also slightly annoying that the error is repeated for every nested quote character, but that also mirrors pyright, although they highlight the whole nested string, which is a little nicer. However, their check is in the analysis phase, so I don't think we have such easy access to the quoted range, at least without adding another mini visitor. ## Test Plan New inline tests [pyright]: https://pyright-play.net/?pythonVersion=3.11&strict=true&code=EYQw5gBAvBAmCWBjALgCgO4gHaygRgEoAoEaCAIgBpyiiBiCLAUwGdknYIBHAVwHt2LIgDMA5AFlwSCJhwAuCAG8IoMAG1Rs2KIC6EAL6iIxosbPmLlq5foRWiEAAcmERAAsQAJxAomnltY2wuSKogA6WKIAdABWfPBYqCAE%2BuSBVqbpWVm2iHwAtvlMWMgB2ekiolUAgq4FjgA2TAAeEMieSADWCsoV5qoaqrrGDJ5MiDz%2B8ABuLqosAIREhlXlaybrmyYMXsDw7V4AnoysyAmQ5SIhwYo3d9cheADUeKlv5O%2BpQA
This commit is contained in:
parent
4ab529803f
commit
dcf31c9348
1
crates/ruff_python_formatter/resources/test/fixtures/black/cases/fstring.options.json
vendored
Normal file
1
crates/ruff_python_formatter/resources/test/fixtures/black/cases/fstring.options.json
vendored
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
{"target_version": "3.12"}
|
||||||
|
|
@ -0,0 +1,12 @@
|
||||||
|
# parse_options: {"target-version": "3.11"}
|
||||||
|
f'Magic wand: { bag['wand'] }' # nested quotes
|
||||||
|
f"{'\n'.join(a)}" # escape sequence
|
||||||
|
f'''A complex trick: {
|
||||||
|
bag['bag'] # comment
|
||||||
|
}'''
|
||||||
|
f"{f"{f"{f"{f"{f"{1+1}"}"}"}"}"}" # arbitrary nesting
|
||||||
|
f"{f'''{"nested"} inner'''} outer" # nested (triple) quotes
|
||||||
|
f"test {a \
|
||||||
|
} more" # line continuation
|
||||||
|
f"""{f"""{x}"""}""" # mark the whole triple quote
|
||||||
|
f"{'\n'.join(['\t', '\v', '\r'])}" # multiple escape sequences, multiple errors
|
||||||
|
|
@ -0,0 +1,7 @@
|
||||||
|
# parse_options: {"target-version": "3.11"}
|
||||||
|
f"outer {'# not a comment'}"
|
||||||
|
f'outer {x:{"# not a comment"} }'
|
||||||
|
f"""{f'''{f'{"# not a comment"}'}'''}"""
|
||||||
|
f"""{f'''# before expression {f'# aro{f"#{1+1}#"}und #'}'''} # after expression"""
|
||||||
|
f"escape outside of \t {expr}\n"
|
||||||
|
f"test\"abcd"
|
||||||
|
|
@ -0,0 +1,10 @@
|
||||||
|
# parse_options: {"target-version": "3.12"}
|
||||||
|
f'Magic wand: { bag['wand'] }' # nested quotes
|
||||||
|
f"{'\n'.join(a)}" # escape sequence
|
||||||
|
f'''A complex trick: {
|
||||||
|
bag['bag'] # comment
|
||||||
|
}'''
|
||||||
|
f"{f"{f"{f"{f"{f"{1+1}"}"}"}"}"}" # arbitrary nesting
|
||||||
|
f"{f'''{"nested"} inner'''} outer" # nested (triple) quotes
|
||||||
|
f"test {a \
|
||||||
|
} more" # line continuation
|
||||||
|
|
@ -452,6 +452,14 @@ pub enum StarTupleKind {
|
||||||
Yield,
|
Yield,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The type of PEP 701 f-string error for [`UnsupportedSyntaxErrorKind::Pep701FString`].
|
||||||
|
#[derive(Debug, PartialEq, Eq, Hash, Clone, Copy)]
|
||||||
|
pub enum FStringKind {
|
||||||
|
Backslash,
|
||||||
|
Comment,
|
||||||
|
NestedQuote,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Eq, Hash, Clone, Copy)]
|
#[derive(Debug, PartialEq, Eq, Hash, Clone, Copy)]
|
||||||
pub enum UnparenthesizedNamedExprKind {
|
pub enum UnparenthesizedNamedExprKind {
|
||||||
SequenceIndex,
|
SequenceIndex,
|
||||||
|
|
@ -661,6 +669,34 @@ pub enum UnsupportedSyntaxErrorKind {
|
||||||
TypeAliasStatement,
|
TypeAliasStatement,
|
||||||
TypeParamDefault,
|
TypeParamDefault,
|
||||||
|
|
||||||
|
/// Represents the use of a [PEP 701] f-string before Python 3.12.
|
||||||
|
///
|
||||||
|
/// ## Examples
|
||||||
|
///
|
||||||
|
/// As described in the PEP, each of these cases were invalid before Python 3.12:
|
||||||
|
///
|
||||||
|
/// ```python
|
||||||
|
/// # nested quotes
|
||||||
|
/// f'Magic wand: { bag['wand'] }'
|
||||||
|
///
|
||||||
|
/// # escape characters
|
||||||
|
/// f"{'\n'.join(a)}"
|
||||||
|
///
|
||||||
|
/// # comments
|
||||||
|
/// f'''A complex trick: {
|
||||||
|
/// bag['bag'] # recursive bags!
|
||||||
|
/// }'''
|
||||||
|
///
|
||||||
|
/// # arbitrary nesting
|
||||||
|
/// f"{f"{f"{f"{f"{f"{1+1}"}"}"}"}"}"
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// These restrictions were lifted in Python 3.12, meaning that all of these examples are now
|
||||||
|
/// valid.
|
||||||
|
///
|
||||||
|
/// [PEP 701]: https://peps.python.org/pep-0701/
|
||||||
|
Pep701FString(FStringKind),
|
||||||
|
|
||||||
/// Represents the use of a parenthesized `with` item before Python 3.9.
|
/// Represents the use of a parenthesized `with` item before Python 3.9.
|
||||||
///
|
///
|
||||||
/// ## Examples
|
/// ## Examples
|
||||||
|
|
@ -838,6 +874,15 @@ impl Display for UnsupportedSyntaxError {
|
||||||
UnsupportedSyntaxErrorKind::TypeParamDefault => {
|
UnsupportedSyntaxErrorKind::TypeParamDefault => {
|
||||||
"Cannot set default type for a type parameter"
|
"Cannot set default type for a type parameter"
|
||||||
}
|
}
|
||||||
|
UnsupportedSyntaxErrorKind::Pep701FString(FStringKind::Backslash) => {
|
||||||
|
"Cannot use an escape sequence (backslash) in f-strings"
|
||||||
|
}
|
||||||
|
UnsupportedSyntaxErrorKind::Pep701FString(FStringKind::Comment) => {
|
||||||
|
"Cannot use comments in f-strings"
|
||||||
|
}
|
||||||
|
UnsupportedSyntaxErrorKind::Pep701FString(FStringKind::NestedQuote) => {
|
||||||
|
"Cannot reuse outer quote character in f-strings"
|
||||||
|
}
|
||||||
UnsupportedSyntaxErrorKind::ParenthesizedContextManager => {
|
UnsupportedSyntaxErrorKind::ParenthesizedContextManager => {
|
||||||
"Cannot use parentheses within a `with` statement"
|
"Cannot use parentheses within a `with` statement"
|
||||||
}
|
}
|
||||||
|
|
@ -904,6 +949,7 @@ impl UnsupportedSyntaxErrorKind {
|
||||||
UnsupportedSyntaxErrorKind::TypeParameterList => Change::Added(PythonVersion::PY312),
|
UnsupportedSyntaxErrorKind::TypeParameterList => Change::Added(PythonVersion::PY312),
|
||||||
UnsupportedSyntaxErrorKind::TypeAliasStatement => Change::Added(PythonVersion::PY312),
|
UnsupportedSyntaxErrorKind::TypeAliasStatement => Change::Added(PythonVersion::PY312),
|
||||||
UnsupportedSyntaxErrorKind::TypeParamDefault => Change::Added(PythonVersion::PY313),
|
UnsupportedSyntaxErrorKind::TypeParamDefault => Change::Added(PythonVersion::PY313),
|
||||||
|
UnsupportedSyntaxErrorKind::Pep701FString(_) => Change::Added(PythonVersion::PY312),
|
||||||
UnsupportedSyntaxErrorKind::ParenthesizedContextManager => {
|
UnsupportedSyntaxErrorKind::ParenthesizedContextManager => {
|
||||||
Change::Added(PythonVersion::PY39)
|
Change::Added(PythonVersion::PY39)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,13 +11,15 @@ use ruff_python_ast::{
|
||||||
};
|
};
|
||||||
use ruff_text_size::{Ranged, TextLen, TextRange, TextSize};
|
use ruff_text_size::{Ranged, TextLen, TextRange, TextSize};
|
||||||
|
|
||||||
use crate::error::{StarTupleKind, UnparenthesizedNamedExprKind};
|
use crate::error::{FStringKind, 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};
|
||||||
use crate::token::{TokenKind, TokenValue};
|
use crate::token::{TokenKind, TokenValue};
|
||||||
use crate::token_set::TokenSet;
|
use crate::token_set::TokenSet;
|
||||||
use crate::{FStringErrorType, Mode, ParseErrorType, UnsupportedSyntaxErrorKind};
|
use crate::{
|
||||||
|
FStringErrorType, Mode, ParseErrorType, UnsupportedSyntaxError, UnsupportedSyntaxErrorKind,
|
||||||
|
};
|
||||||
|
|
||||||
use super::{FStringElementsKind, Parenthesized, RecoveryContextKind};
|
use super::{FStringElementsKind, Parenthesized, RecoveryContextKind};
|
||||||
|
|
||||||
|
|
@ -1393,13 +1395,89 @@ impl<'src> Parser<'src> {
|
||||||
|
|
||||||
self.expect(TokenKind::FStringEnd);
|
self.expect(TokenKind::FStringEnd);
|
||||||
|
|
||||||
|
// test_ok pep701_f_string_py312
|
||||||
|
// # parse_options: {"target-version": "3.12"}
|
||||||
|
// f'Magic wand: { bag['wand'] }' # nested quotes
|
||||||
|
// f"{'\n'.join(a)}" # escape sequence
|
||||||
|
// f'''A complex trick: {
|
||||||
|
// bag['bag'] # comment
|
||||||
|
// }'''
|
||||||
|
// f"{f"{f"{f"{f"{f"{1+1}"}"}"}"}"}" # arbitrary nesting
|
||||||
|
// f"{f'''{"nested"} inner'''} outer" # nested (triple) quotes
|
||||||
|
// f"test {a \
|
||||||
|
// } more" # line continuation
|
||||||
|
|
||||||
|
// test_ok pep701_f_string_py311
|
||||||
|
// # parse_options: {"target-version": "3.11"}
|
||||||
|
// f"outer {'# not a comment'}"
|
||||||
|
// f'outer {x:{"# not a comment"} }'
|
||||||
|
// f"""{f'''{f'{"# not a comment"}'}'''}"""
|
||||||
|
// f"""{f'''# before expression {f'# aro{f"#{1+1}#"}und #'}'''} # after expression"""
|
||||||
|
// f"escape outside of \t {expr}\n"
|
||||||
|
// f"test\"abcd"
|
||||||
|
|
||||||
|
// test_err pep701_f_string_py311
|
||||||
|
// # parse_options: {"target-version": "3.11"}
|
||||||
|
// f'Magic wand: { bag['wand'] }' # nested quotes
|
||||||
|
// f"{'\n'.join(a)}" # escape sequence
|
||||||
|
// f'''A complex trick: {
|
||||||
|
// bag['bag'] # comment
|
||||||
|
// }'''
|
||||||
|
// f"{f"{f"{f"{f"{f"{1+1}"}"}"}"}"}" # arbitrary nesting
|
||||||
|
// f"{f'''{"nested"} inner'''} outer" # nested (triple) quotes
|
||||||
|
// f"test {a \
|
||||||
|
// } more" # line continuation
|
||||||
|
// f"""{f"""{x}"""}""" # mark the whole triple quote
|
||||||
|
// f"{'\n'.join(['\t', '\v', '\r'])}" # multiple escape sequences, multiple errors
|
||||||
|
|
||||||
|
let range = self.node_range(start);
|
||||||
|
|
||||||
|
if !self.options.target_version.supports_pep_701() {
|
||||||
|
let quote_bytes = flags.quote_str().as_bytes();
|
||||||
|
let quote_len = flags.quote_len();
|
||||||
|
for expr in elements.expressions() {
|
||||||
|
for slash_position in memchr::memchr_iter(b'\\', self.source[expr.range].as_bytes())
|
||||||
|
{
|
||||||
|
let slash_position = TextSize::try_from(slash_position).unwrap();
|
||||||
|
self.add_unsupported_syntax_error(
|
||||||
|
UnsupportedSyntaxErrorKind::Pep701FString(FStringKind::Backslash),
|
||||||
|
TextRange::at(expr.range.start() + slash_position, '\\'.text_len()),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(quote_position) =
|
||||||
|
memchr::memmem::find(self.source[expr.range].as_bytes(), quote_bytes)
|
||||||
|
{
|
||||||
|
let quote_position = TextSize::try_from(quote_position).unwrap();
|
||||||
|
self.add_unsupported_syntax_error(
|
||||||
|
UnsupportedSyntaxErrorKind::Pep701FString(FStringKind::NestedQuote),
|
||||||
|
TextRange::at(expr.range.start() + quote_position, quote_len),
|
||||||
|
);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
self.check_fstring_comments(range);
|
||||||
|
}
|
||||||
|
|
||||||
ast::FString {
|
ast::FString {
|
||||||
elements,
|
elements,
|
||||||
range: self.node_range(start),
|
range,
|
||||||
flags: ast::FStringFlags::from(flags),
|
flags: ast::FStringFlags::from(flags),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Check `range` for comment tokens and report an `UnsupportedSyntaxError` for each one found.
|
||||||
|
fn check_fstring_comments(&mut self, range: TextRange) {
|
||||||
|
self.unsupported_syntax_errors
|
||||||
|
.extend(self.tokens.in_range(range).iter().filter_map(|token| {
|
||||||
|
token.kind().is_comment().then_some(UnsupportedSyntaxError {
|
||||||
|
kind: UnsupportedSyntaxErrorKind::Pep701FString(FStringKind::Comment),
|
||||||
|
range: token.range(),
|
||||||
|
target_version: self.options.target_version,
|
||||||
|
})
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
/// Parses a list of f-string elements.
|
/// Parses a list of f-string elements.
|
||||||
///
|
///
|
||||||
/// # Panics
|
/// # Panics
|
||||||
|
|
|
||||||
|
|
@ -418,6 +418,12 @@ impl TokenKind {
|
||||||
matches!(self, TokenKind::Comment | TokenKind::NonLogicalNewline)
|
matches!(self, TokenKind::Comment | TokenKind::NonLogicalNewline)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns `true` if this is a comment token.
|
||||||
|
#[inline]
|
||||||
|
pub const fn is_comment(&self) -> bool {
|
||||||
|
matches!(self, TokenKind::Comment)
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub const fn is_arithmetic(self) -> bool {
|
pub const fn is_arithmetic(self) -> bool {
|
||||||
matches!(
|
matches!(
|
||||||
|
|
|
||||||
|
|
@ -166,6 +166,21 @@ impl<'src> TokenSource<'src> {
|
||||||
self.tokens.truncate(tokens_position);
|
self.tokens.truncate(tokens_position);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns a slice of [`Token`] that are within the given `range`.
|
||||||
|
pub(crate) fn in_range(&self, range: TextRange) -> &[Token] {
|
||||||
|
let start = self
|
||||||
|
.tokens
|
||||||
|
.iter()
|
||||||
|
.rposition(|tok| tok.start() == range.start());
|
||||||
|
let end = self.tokens.iter().rposition(|tok| tok.end() == range.end());
|
||||||
|
|
||||||
|
let (Some(start), Some(end)) = (start, end) else {
|
||||||
|
return &self.tokens;
|
||||||
|
};
|
||||||
|
|
||||||
|
&self.tokens[start..=end]
|
||||||
|
}
|
||||||
|
|
||||||
/// Consumes the token source, returning the collected tokens, comment ranges, and any errors
|
/// Consumes the token source, returning the collected tokens, comment ranges, and any errors
|
||||||
/// encountered during lexing. The token collection includes both the trivia and non-trivia
|
/// encountered during lexing. The token collection includes both the trivia and non-trivia
|
||||||
/// tokens.
|
/// tokens.
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,929 @@
|
||||||
|
---
|
||||||
|
source: crates/ruff_python_parser/tests/fixtures.rs
|
||||||
|
input_file: crates/ruff_python_parser/resources/inline/err/pep701_f_string_py311.py
|
||||||
|
---
|
||||||
|
## AST
|
||||||
|
|
||||||
|
```
|
||||||
|
Module(
|
||||||
|
ModModule {
|
||||||
|
range: 0..549,
|
||||||
|
body: [
|
||||||
|
Expr(
|
||||||
|
StmtExpr {
|
||||||
|
range: 44..74,
|
||||||
|
value: FString(
|
||||||
|
ExprFString {
|
||||||
|
range: 44..74,
|
||||||
|
value: FStringValue {
|
||||||
|
inner: Single(
|
||||||
|
FString(
|
||||||
|
FString {
|
||||||
|
range: 44..74,
|
||||||
|
elements: [
|
||||||
|
Literal(
|
||||||
|
FStringLiteralElement {
|
||||||
|
range: 46..58,
|
||||||
|
value: "Magic wand: ",
|
||||||
|
},
|
||||||
|
),
|
||||||
|
Expression(
|
||||||
|
FStringExpressionElement {
|
||||||
|
range: 58..73,
|
||||||
|
expression: Subscript(
|
||||||
|
ExprSubscript {
|
||||||
|
range: 60..71,
|
||||||
|
value: Name(
|
||||||
|
ExprName {
|
||||||
|
range: 60..63,
|
||||||
|
id: Name("bag"),
|
||||||
|
ctx: Load,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
slice: StringLiteral(
|
||||||
|
ExprStringLiteral {
|
||||||
|
range: 64..70,
|
||||||
|
value: StringLiteralValue {
|
||||||
|
inner: Single(
|
||||||
|
StringLiteral {
|
||||||
|
range: 64..70,
|
||||||
|
value: "wand",
|
||||||
|
flags: StringLiteralFlags {
|
||||||
|
quote_style: Single,
|
||||||
|
prefix: Empty,
|
||||||
|
triple_quoted: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
ctx: Load,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
debug_text: None,
|
||||||
|
conversion: None,
|
||||||
|
format_spec: None,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
flags: FStringFlags {
|
||||||
|
quote_style: Single,
|
||||||
|
prefix: Regular,
|
||||||
|
triple_quoted: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
Expr(
|
||||||
|
StmtExpr {
|
||||||
|
range: 95..112,
|
||||||
|
value: FString(
|
||||||
|
ExprFString {
|
||||||
|
range: 95..112,
|
||||||
|
value: FStringValue {
|
||||||
|
inner: Single(
|
||||||
|
FString(
|
||||||
|
FString {
|
||||||
|
range: 95..112,
|
||||||
|
elements: [
|
||||||
|
Expression(
|
||||||
|
FStringExpressionElement {
|
||||||
|
range: 97..111,
|
||||||
|
expression: Call(
|
||||||
|
ExprCall {
|
||||||
|
range: 98..110,
|
||||||
|
func: Attribute(
|
||||||
|
ExprAttribute {
|
||||||
|
range: 98..107,
|
||||||
|
value: StringLiteral(
|
||||||
|
ExprStringLiteral {
|
||||||
|
range: 98..102,
|
||||||
|
value: StringLiteralValue {
|
||||||
|
inner: Single(
|
||||||
|
StringLiteral {
|
||||||
|
range: 98..102,
|
||||||
|
value: "\n",
|
||||||
|
flags: StringLiteralFlags {
|
||||||
|
quote_style: Single,
|
||||||
|
prefix: Empty,
|
||||||
|
triple_quoted: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
attr: Identifier {
|
||||||
|
id: Name("join"),
|
||||||
|
range: 103..107,
|
||||||
|
},
|
||||||
|
ctx: Load,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
arguments: Arguments {
|
||||||
|
range: 107..110,
|
||||||
|
args: [
|
||||||
|
Name(
|
||||||
|
ExprName {
|
||||||
|
range: 108..109,
|
||||||
|
id: Name("a"),
|
||||||
|
ctx: Load,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
keywords: [],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
debug_text: None,
|
||||||
|
conversion: None,
|
||||||
|
format_spec: None,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
flags: FStringFlags {
|
||||||
|
quote_style: Double,
|
||||||
|
prefix: Regular,
|
||||||
|
triple_quoted: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
Expr(
|
||||||
|
StmtExpr {
|
||||||
|
range: 148..220,
|
||||||
|
value: FString(
|
||||||
|
ExprFString {
|
||||||
|
range: 148..220,
|
||||||
|
value: FStringValue {
|
||||||
|
inner: Single(
|
||||||
|
FString(
|
||||||
|
FString {
|
||||||
|
range: 148..220,
|
||||||
|
elements: [
|
||||||
|
Literal(
|
||||||
|
FStringLiteralElement {
|
||||||
|
range: 152..169,
|
||||||
|
value: "A complex trick: ",
|
||||||
|
},
|
||||||
|
),
|
||||||
|
Expression(
|
||||||
|
FStringExpressionElement {
|
||||||
|
range: 169..217,
|
||||||
|
expression: Subscript(
|
||||||
|
ExprSubscript {
|
||||||
|
range: 175..185,
|
||||||
|
value: Name(
|
||||||
|
ExprName {
|
||||||
|
range: 175..178,
|
||||||
|
id: Name("bag"),
|
||||||
|
ctx: Load,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
slice: StringLiteral(
|
||||||
|
ExprStringLiteral {
|
||||||
|
range: 179..184,
|
||||||
|
value: StringLiteralValue {
|
||||||
|
inner: Single(
|
||||||
|
StringLiteral {
|
||||||
|
range: 179..184,
|
||||||
|
value: "bag",
|
||||||
|
flags: StringLiteralFlags {
|
||||||
|
quote_style: Single,
|
||||||
|
prefix: Empty,
|
||||||
|
triple_quoted: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
ctx: Load,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
debug_text: None,
|
||||||
|
conversion: None,
|
||||||
|
format_spec: None,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
flags: FStringFlags {
|
||||||
|
quote_style: Single,
|
||||||
|
prefix: Regular,
|
||||||
|
triple_quoted: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
Expr(
|
||||||
|
StmtExpr {
|
||||||
|
range: 221..254,
|
||||||
|
value: FString(
|
||||||
|
ExprFString {
|
||||||
|
range: 221..254,
|
||||||
|
value: FStringValue {
|
||||||
|
inner: Single(
|
||||||
|
FString(
|
||||||
|
FString {
|
||||||
|
range: 221..254,
|
||||||
|
elements: [
|
||||||
|
Expression(
|
||||||
|
FStringExpressionElement {
|
||||||
|
range: 223..253,
|
||||||
|
expression: FString(
|
||||||
|
ExprFString {
|
||||||
|
range: 224..252,
|
||||||
|
value: FStringValue {
|
||||||
|
inner: Single(
|
||||||
|
FString(
|
||||||
|
FString {
|
||||||
|
range: 224..252,
|
||||||
|
elements: [
|
||||||
|
Expression(
|
||||||
|
FStringExpressionElement {
|
||||||
|
range: 226..251,
|
||||||
|
expression: FString(
|
||||||
|
ExprFString {
|
||||||
|
range: 227..250,
|
||||||
|
value: FStringValue {
|
||||||
|
inner: Single(
|
||||||
|
FString(
|
||||||
|
FString {
|
||||||
|
range: 227..250,
|
||||||
|
elements: [
|
||||||
|
Expression(
|
||||||
|
FStringExpressionElement {
|
||||||
|
range: 229..249,
|
||||||
|
expression: FString(
|
||||||
|
ExprFString {
|
||||||
|
range: 230..248,
|
||||||
|
value: FStringValue {
|
||||||
|
inner: Single(
|
||||||
|
FString(
|
||||||
|
FString {
|
||||||
|
range: 230..248,
|
||||||
|
elements: [
|
||||||
|
Expression(
|
||||||
|
FStringExpressionElement {
|
||||||
|
range: 232..247,
|
||||||
|
expression: FString(
|
||||||
|
ExprFString {
|
||||||
|
range: 233..246,
|
||||||
|
value: FStringValue {
|
||||||
|
inner: Single(
|
||||||
|
FString(
|
||||||
|
FString {
|
||||||
|
range: 233..246,
|
||||||
|
elements: [
|
||||||
|
Expression(
|
||||||
|
FStringExpressionElement {
|
||||||
|
range: 235..245,
|
||||||
|
expression: FString(
|
||||||
|
ExprFString {
|
||||||
|
range: 236..244,
|
||||||
|
value: FStringValue {
|
||||||
|
inner: Single(
|
||||||
|
FString(
|
||||||
|
FString {
|
||||||
|
range: 236..244,
|
||||||
|
elements: [
|
||||||
|
Expression(
|
||||||
|
FStringExpressionElement {
|
||||||
|
range: 238..243,
|
||||||
|
expression: BinOp(
|
||||||
|
ExprBinOp {
|
||||||
|
range: 239..242,
|
||||||
|
left: NumberLiteral(
|
||||||
|
ExprNumberLiteral {
|
||||||
|
range: 239..240,
|
||||||
|
value: Int(
|
||||||
|
1,
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
op: Add,
|
||||||
|
right: NumberLiteral(
|
||||||
|
ExprNumberLiteral {
|
||||||
|
range: 241..242,
|
||||||
|
value: Int(
|
||||||
|
1,
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
debug_text: None,
|
||||||
|
conversion: None,
|
||||||
|
format_spec: None,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
flags: FStringFlags {
|
||||||
|
quote_style: Double,
|
||||||
|
prefix: Regular,
|
||||||
|
triple_quoted: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
debug_text: None,
|
||||||
|
conversion: None,
|
||||||
|
format_spec: None,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
flags: FStringFlags {
|
||||||
|
quote_style: Double,
|
||||||
|
prefix: Regular,
|
||||||
|
triple_quoted: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
debug_text: None,
|
||||||
|
conversion: None,
|
||||||
|
format_spec: None,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
flags: FStringFlags {
|
||||||
|
quote_style: Double,
|
||||||
|
prefix: Regular,
|
||||||
|
triple_quoted: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
debug_text: None,
|
||||||
|
conversion: None,
|
||||||
|
format_spec: None,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
flags: FStringFlags {
|
||||||
|
quote_style: Double,
|
||||||
|
prefix: Regular,
|
||||||
|
triple_quoted: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
debug_text: None,
|
||||||
|
conversion: None,
|
||||||
|
format_spec: None,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
flags: FStringFlags {
|
||||||
|
quote_style: Double,
|
||||||
|
prefix: Regular,
|
||||||
|
triple_quoted: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
debug_text: None,
|
||||||
|
conversion: None,
|
||||||
|
format_spec: None,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
flags: FStringFlags {
|
||||||
|
quote_style: Double,
|
||||||
|
prefix: Regular,
|
||||||
|
triple_quoted: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
Expr(
|
||||||
|
StmtExpr {
|
||||||
|
range: 276..310,
|
||||||
|
value: FString(
|
||||||
|
ExprFString {
|
||||||
|
range: 276..310,
|
||||||
|
value: FStringValue {
|
||||||
|
inner: Single(
|
||||||
|
FString(
|
||||||
|
FString {
|
||||||
|
range: 276..310,
|
||||||
|
elements: [
|
||||||
|
Expression(
|
||||||
|
FStringExpressionElement {
|
||||||
|
range: 278..303,
|
||||||
|
expression: FString(
|
||||||
|
ExprFString {
|
||||||
|
range: 279..302,
|
||||||
|
value: FStringValue {
|
||||||
|
inner: Single(
|
||||||
|
FString(
|
||||||
|
FString {
|
||||||
|
range: 279..302,
|
||||||
|
elements: [
|
||||||
|
Expression(
|
||||||
|
FStringExpressionElement {
|
||||||
|
range: 283..293,
|
||||||
|
expression: StringLiteral(
|
||||||
|
ExprStringLiteral {
|
||||||
|
range: 284..292,
|
||||||
|
value: StringLiteralValue {
|
||||||
|
inner: Single(
|
||||||
|
StringLiteral {
|
||||||
|
range: 284..292,
|
||||||
|
value: "nested",
|
||||||
|
flags: StringLiteralFlags {
|
||||||
|
quote_style: Double,
|
||||||
|
prefix: Empty,
|
||||||
|
triple_quoted: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
debug_text: None,
|
||||||
|
conversion: None,
|
||||||
|
format_spec: None,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
Literal(
|
||||||
|
FStringLiteralElement {
|
||||||
|
range: 293..299,
|
||||||
|
value: " inner",
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
flags: FStringFlags {
|
||||||
|
quote_style: Single,
|
||||||
|
prefix: Regular,
|
||||||
|
triple_quoted: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
debug_text: None,
|
||||||
|
conversion: None,
|
||||||
|
format_spec: None,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
Literal(
|
||||||
|
FStringLiteralElement {
|
||||||
|
range: 303..309,
|
||||||
|
value: " outer",
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
flags: FStringFlags {
|
||||||
|
quote_style: Double,
|
||||||
|
prefix: Regular,
|
||||||
|
triple_quoted: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
Expr(
|
||||||
|
StmtExpr {
|
||||||
|
range: 336..359,
|
||||||
|
value: FString(
|
||||||
|
ExprFString {
|
||||||
|
range: 336..359,
|
||||||
|
value: FStringValue {
|
||||||
|
inner: Single(
|
||||||
|
FString(
|
||||||
|
FString {
|
||||||
|
range: 336..359,
|
||||||
|
elements: [
|
||||||
|
Literal(
|
||||||
|
FStringLiteralElement {
|
||||||
|
range: 338..343,
|
||||||
|
value: "test ",
|
||||||
|
},
|
||||||
|
),
|
||||||
|
Expression(
|
||||||
|
FStringExpressionElement {
|
||||||
|
range: 343..353,
|
||||||
|
expression: Name(
|
||||||
|
ExprName {
|
||||||
|
range: 344..345,
|
||||||
|
id: Name("a"),
|
||||||
|
ctx: Load,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
debug_text: None,
|
||||||
|
conversion: None,
|
||||||
|
format_spec: None,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
Literal(
|
||||||
|
FStringLiteralElement {
|
||||||
|
range: 353..358,
|
||||||
|
value: " more",
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
flags: FStringFlags {
|
||||||
|
quote_style: Double,
|
||||||
|
prefix: Regular,
|
||||||
|
triple_quoted: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
Expr(
|
||||||
|
StmtExpr {
|
||||||
|
range: 403..422,
|
||||||
|
value: FString(
|
||||||
|
ExprFString {
|
||||||
|
range: 403..422,
|
||||||
|
value: FStringValue {
|
||||||
|
inner: Single(
|
||||||
|
FString(
|
||||||
|
FString {
|
||||||
|
range: 403..422,
|
||||||
|
elements: [
|
||||||
|
Expression(
|
||||||
|
FStringExpressionElement {
|
||||||
|
range: 407..419,
|
||||||
|
expression: FString(
|
||||||
|
ExprFString {
|
||||||
|
range: 408..418,
|
||||||
|
value: FStringValue {
|
||||||
|
inner: Single(
|
||||||
|
FString(
|
||||||
|
FString {
|
||||||
|
range: 408..418,
|
||||||
|
elements: [
|
||||||
|
Expression(
|
||||||
|
FStringExpressionElement {
|
||||||
|
range: 412..415,
|
||||||
|
expression: Name(
|
||||||
|
ExprName {
|
||||||
|
range: 413..414,
|
||||||
|
id: Name("x"),
|
||||||
|
ctx: Load,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
debug_text: None,
|
||||||
|
conversion: None,
|
||||||
|
format_spec: None,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
flags: FStringFlags {
|
||||||
|
quote_style: Double,
|
||||||
|
prefix: Regular,
|
||||||
|
triple_quoted: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
debug_text: None,
|
||||||
|
conversion: None,
|
||||||
|
format_spec: None,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
flags: FStringFlags {
|
||||||
|
quote_style: Double,
|
||||||
|
prefix: Regular,
|
||||||
|
triple_quoted: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
Expr(
|
||||||
|
StmtExpr {
|
||||||
|
range: 468..502,
|
||||||
|
value: FString(
|
||||||
|
ExprFString {
|
||||||
|
range: 468..502,
|
||||||
|
value: FStringValue {
|
||||||
|
inner: Single(
|
||||||
|
FString(
|
||||||
|
FString {
|
||||||
|
range: 468..502,
|
||||||
|
elements: [
|
||||||
|
Expression(
|
||||||
|
FStringExpressionElement {
|
||||||
|
range: 470..501,
|
||||||
|
expression: Call(
|
||||||
|
ExprCall {
|
||||||
|
range: 471..500,
|
||||||
|
func: Attribute(
|
||||||
|
ExprAttribute {
|
||||||
|
range: 471..480,
|
||||||
|
value: StringLiteral(
|
||||||
|
ExprStringLiteral {
|
||||||
|
range: 471..475,
|
||||||
|
value: StringLiteralValue {
|
||||||
|
inner: Single(
|
||||||
|
StringLiteral {
|
||||||
|
range: 471..475,
|
||||||
|
value: "\n",
|
||||||
|
flags: StringLiteralFlags {
|
||||||
|
quote_style: Single,
|
||||||
|
prefix: Empty,
|
||||||
|
triple_quoted: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
attr: Identifier {
|
||||||
|
id: Name("join"),
|
||||||
|
range: 476..480,
|
||||||
|
},
|
||||||
|
ctx: Load,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
arguments: Arguments {
|
||||||
|
range: 480..500,
|
||||||
|
args: [
|
||||||
|
List(
|
||||||
|
ExprList {
|
||||||
|
range: 481..499,
|
||||||
|
elts: [
|
||||||
|
StringLiteral(
|
||||||
|
ExprStringLiteral {
|
||||||
|
range: 482..486,
|
||||||
|
value: StringLiteralValue {
|
||||||
|
inner: Single(
|
||||||
|
StringLiteral {
|
||||||
|
range: 482..486,
|
||||||
|
value: "\t",
|
||||||
|
flags: StringLiteralFlags {
|
||||||
|
quote_style: Single,
|
||||||
|
prefix: Empty,
|
||||||
|
triple_quoted: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
StringLiteral(
|
||||||
|
ExprStringLiteral {
|
||||||
|
range: 488..492,
|
||||||
|
value: StringLiteralValue {
|
||||||
|
inner: Single(
|
||||||
|
StringLiteral {
|
||||||
|
range: 488..492,
|
||||||
|
value: "\u{b}",
|
||||||
|
flags: StringLiteralFlags {
|
||||||
|
quote_style: Single,
|
||||||
|
prefix: Empty,
|
||||||
|
triple_quoted: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
StringLiteral(
|
||||||
|
ExprStringLiteral {
|
||||||
|
range: 494..498,
|
||||||
|
value: StringLiteralValue {
|
||||||
|
inner: Single(
|
||||||
|
StringLiteral {
|
||||||
|
range: 494..498,
|
||||||
|
value: "\r",
|
||||||
|
flags: StringLiteralFlags {
|
||||||
|
quote_style: Single,
|
||||||
|
prefix: Empty,
|
||||||
|
triple_quoted: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
ctx: Load,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
keywords: [],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
debug_text: None,
|
||||||
|
conversion: None,
|
||||||
|
format_spec: None,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
flags: FStringFlags {
|
||||||
|
quote_style: Double,
|
||||||
|
prefix: Regular,
|
||||||
|
triple_quoted: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
)
|
||||||
|
```
|
||||||
|
## Unsupported Syntax Errors
|
||||||
|
|
||||||
|
|
|
||||||
|
1 | # parse_options: {"target-version": "3.11"}
|
||||||
|
2 | f'Magic wand: { bag['wand'] }' # nested quotes
|
||||||
|
| ^ Syntax Error: Cannot reuse outer quote character in f-strings on Python 3.11 (syntax was added in Python 3.12)
|
||||||
|
3 | f"{'\n'.join(a)}" # escape sequence
|
||||||
|
4 | f'''A complex trick: {
|
||||||
|
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
1 | # parse_options: {"target-version": "3.11"}
|
||||||
|
2 | f'Magic wand: { bag['wand'] }' # nested quotes
|
||||||
|
3 | f"{'\n'.join(a)}" # escape sequence
|
||||||
|
| ^ Syntax Error: Cannot use an escape sequence (backslash) in f-strings on Python 3.11 (syntax was added in Python 3.12)
|
||||||
|
4 | f'''A complex trick: {
|
||||||
|
5 | bag['bag'] # comment
|
||||||
|
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
3 | f"{'\n'.join(a)}" # escape sequence
|
||||||
|
4 | f'''A complex trick: {
|
||||||
|
5 | bag['bag'] # comment
|
||||||
|
| ^^^^^^^^^ Syntax Error: Cannot use comments in f-strings on Python 3.11 (syntax was added in Python 3.12)
|
||||||
|
6 | }'''
|
||||||
|
7 | f"{f"{f"{f"{f"{f"{1+1}"}"}"}"}"}" # arbitrary nesting
|
||||||
|
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
5 | bag['bag'] # comment
|
||||||
|
6 | }'''
|
||||||
|
7 | f"{f"{f"{f"{f"{f"{1+1}"}"}"}"}"}" # arbitrary nesting
|
||||||
|
| ^ Syntax Error: Cannot reuse outer quote character in f-strings on Python 3.11 (syntax was added in Python 3.12)
|
||||||
|
8 | f"{f'''{"nested"} inner'''} outer" # nested (triple) quotes
|
||||||
|
9 | f"test {a \
|
||||||
|
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
5 | bag['bag'] # comment
|
||||||
|
6 | }'''
|
||||||
|
7 | f"{f"{f"{f"{f"{f"{1+1}"}"}"}"}"}" # arbitrary nesting
|
||||||
|
| ^ Syntax Error: Cannot reuse outer quote character in f-strings on Python 3.11 (syntax was added in Python 3.12)
|
||||||
|
8 | f"{f'''{"nested"} inner'''} outer" # nested (triple) quotes
|
||||||
|
9 | f"test {a \
|
||||||
|
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
5 | bag['bag'] # comment
|
||||||
|
6 | }'''
|
||||||
|
7 | f"{f"{f"{f"{f"{f"{1+1}"}"}"}"}"}" # arbitrary nesting
|
||||||
|
| ^ Syntax Error: Cannot reuse outer quote character in f-strings on Python 3.11 (syntax was added in Python 3.12)
|
||||||
|
8 | f"{f'''{"nested"} inner'''} outer" # nested (triple) quotes
|
||||||
|
9 | f"test {a \
|
||||||
|
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
5 | bag['bag'] # comment
|
||||||
|
6 | }'''
|
||||||
|
7 | f"{f"{f"{f"{f"{f"{1+1}"}"}"}"}"}" # arbitrary nesting
|
||||||
|
| ^ Syntax Error: Cannot reuse outer quote character in f-strings on Python 3.11 (syntax was added in Python 3.12)
|
||||||
|
8 | f"{f'''{"nested"} inner'''} outer" # nested (triple) quotes
|
||||||
|
9 | f"test {a \
|
||||||
|
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
5 | bag['bag'] # comment
|
||||||
|
6 | }'''
|
||||||
|
7 | f"{f"{f"{f"{f"{f"{1+1}"}"}"}"}"}" # arbitrary nesting
|
||||||
|
| ^ Syntax Error: Cannot reuse outer quote character in f-strings on Python 3.11 (syntax was added in Python 3.12)
|
||||||
|
8 | f"{f'''{"nested"} inner'''} outer" # nested (triple) quotes
|
||||||
|
9 | f"test {a \
|
||||||
|
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
6 | }'''
|
||||||
|
7 | f"{f"{f"{f"{f"{f"{1+1}"}"}"}"}"}" # arbitrary nesting
|
||||||
|
8 | f"{f'''{"nested"} inner'''} outer" # nested (triple) quotes
|
||||||
|
| ^ Syntax Error: Cannot reuse outer quote character in f-strings on Python 3.11 (syntax was added in Python 3.12)
|
||||||
|
9 | f"test {a \
|
||||||
|
10 | } more" # line continuation
|
||||||
|
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
7 | f"{f"{f"{f"{f"{f"{1+1}"}"}"}"}"}" # arbitrary nesting
|
||||||
|
8 | f"{f'''{"nested"} inner'''} outer" # nested (triple) quotes
|
||||||
|
9 | f"test {a \
|
||||||
|
| ^ Syntax Error: Cannot use an escape sequence (backslash) in f-strings on Python 3.11 (syntax was added in Python 3.12)
|
||||||
|
10 | } more" # line continuation
|
||||||
|
11 | f"""{f"""{x}"""}""" # mark the whole triple quote
|
||||||
|
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
9 | f"test {a \
|
||||||
|
10 | } more" # line continuation
|
||||||
|
11 | f"""{f"""{x}"""}""" # mark the whole triple quote
|
||||||
|
| ^^^ Syntax Error: Cannot reuse outer quote character in f-strings on Python 3.11 (syntax was added in Python 3.12)
|
||||||
|
12 | f"{'\n'.join(['\t', '\v', '\r'])}" # multiple escape sequences, multiple errors
|
||||||
|
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
10 | } more" # line continuation
|
||||||
|
11 | f"""{f"""{x}"""}""" # mark the whole triple quote
|
||||||
|
12 | f"{'\n'.join(['\t', '\v', '\r'])}" # multiple escape sequences, multiple errors
|
||||||
|
| ^ Syntax Error: Cannot use an escape sequence (backslash) in f-strings on Python 3.11 (syntax was added in Python 3.12)
|
||||||
|
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
10 | } more" # line continuation
|
||||||
|
11 | f"""{f"""{x}"""}""" # mark the whole triple quote
|
||||||
|
12 | f"{'\n'.join(['\t', '\v', '\r'])}" # multiple escape sequences, multiple errors
|
||||||
|
| ^ Syntax Error: Cannot use an escape sequence (backslash) in f-strings on Python 3.11 (syntax was added in Python 3.12)
|
||||||
|
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
10 | } more" # line continuation
|
||||||
|
11 | f"""{f"""{x}"""}""" # mark the whole triple quote
|
||||||
|
12 | f"{'\n'.join(['\t', '\v', '\r'])}" # multiple escape sequences, multiple errors
|
||||||
|
| ^ Syntax Error: Cannot use an escape sequence (backslash) in f-strings on Python 3.11 (syntax was added in Python 3.12)
|
||||||
|
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
10 | } more" # line continuation
|
||||||
|
11 | f"""{f"""{x}"""}""" # mark the whole triple quote
|
||||||
|
12 | f"{'\n'.join(['\t', '\v', '\r'])}" # multiple escape sequences, multiple errors
|
||||||
|
| ^ Syntax Error: Cannot use an escape sequence (backslash) in f-strings on Python 3.11 (syntax was added in Python 3.12)
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,532 @@
|
||||||
|
---
|
||||||
|
source: crates/ruff_python_parser/tests/fixtures.rs
|
||||||
|
input_file: crates/ruff_python_parser/resources/inline/ok/pep701_f_string_py311.py
|
||||||
|
---
|
||||||
|
## AST
|
||||||
|
|
||||||
|
```
|
||||||
|
Module(
|
||||||
|
ModModule {
|
||||||
|
range: 0..278,
|
||||||
|
body: [
|
||||||
|
Expr(
|
||||||
|
StmtExpr {
|
||||||
|
range: 44..72,
|
||||||
|
value: FString(
|
||||||
|
ExprFString {
|
||||||
|
range: 44..72,
|
||||||
|
value: FStringValue {
|
||||||
|
inner: Single(
|
||||||
|
FString(
|
||||||
|
FString {
|
||||||
|
range: 44..72,
|
||||||
|
elements: [
|
||||||
|
Literal(
|
||||||
|
FStringLiteralElement {
|
||||||
|
range: 46..52,
|
||||||
|
value: "outer ",
|
||||||
|
},
|
||||||
|
),
|
||||||
|
Expression(
|
||||||
|
FStringExpressionElement {
|
||||||
|
range: 52..71,
|
||||||
|
expression: StringLiteral(
|
||||||
|
ExprStringLiteral {
|
||||||
|
range: 53..70,
|
||||||
|
value: StringLiteralValue {
|
||||||
|
inner: Single(
|
||||||
|
StringLiteral {
|
||||||
|
range: 53..70,
|
||||||
|
value: "# not a comment",
|
||||||
|
flags: StringLiteralFlags {
|
||||||
|
quote_style: Single,
|
||||||
|
prefix: Empty,
|
||||||
|
triple_quoted: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
debug_text: None,
|
||||||
|
conversion: None,
|
||||||
|
format_spec: None,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
flags: FStringFlags {
|
||||||
|
quote_style: Double,
|
||||||
|
prefix: Regular,
|
||||||
|
triple_quoted: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
Expr(
|
||||||
|
StmtExpr {
|
||||||
|
range: 73..106,
|
||||||
|
value: FString(
|
||||||
|
ExprFString {
|
||||||
|
range: 73..106,
|
||||||
|
value: FStringValue {
|
||||||
|
inner: Single(
|
||||||
|
FString(
|
||||||
|
FString {
|
||||||
|
range: 73..106,
|
||||||
|
elements: [
|
||||||
|
Literal(
|
||||||
|
FStringLiteralElement {
|
||||||
|
range: 75..81,
|
||||||
|
value: "outer ",
|
||||||
|
},
|
||||||
|
),
|
||||||
|
Expression(
|
||||||
|
FStringExpressionElement {
|
||||||
|
range: 81..105,
|
||||||
|
expression: Name(
|
||||||
|
ExprName {
|
||||||
|
range: 82..83,
|
||||||
|
id: Name("x"),
|
||||||
|
ctx: Load,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
debug_text: None,
|
||||||
|
conversion: None,
|
||||||
|
format_spec: Some(
|
||||||
|
FStringFormatSpec {
|
||||||
|
range: 84..104,
|
||||||
|
elements: [
|
||||||
|
Expression(
|
||||||
|
FStringExpressionElement {
|
||||||
|
range: 84..103,
|
||||||
|
expression: StringLiteral(
|
||||||
|
ExprStringLiteral {
|
||||||
|
range: 85..102,
|
||||||
|
value: StringLiteralValue {
|
||||||
|
inner: Single(
|
||||||
|
StringLiteral {
|
||||||
|
range: 85..102,
|
||||||
|
value: "# not a comment",
|
||||||
|
flags: StringLiteralFlags {
|
||||||
|
quote_style: Double,
|
||||||
|
prefix: Empty,
|
||||||
|
triple_quoted: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
debug_text: None,
|
||||||
|
conversion: None,
|
||||||
|
format_spec: None,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
Literal(
|
||||||
|
FStringLiteralElement {
|
||||||
|
range: 103..104,
|
||||||
|
value: " ",
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
flags: FStringFlags {
|
||||||
|
quote_style: Single,
|
||||||
|
prefix: Regular,
|
||||||
|
triple_quoted: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
Expr(
|
||||||
|
StmtExpr {
|
||||||
|
range: 107..147,
|
||||||
|
value: FString(
|
||||||
|
ExprFString {
|
||||||
|
range: 107..147,
|
||||||
|
value: FStringValue {
|
||||||
|
inner: Single(
|
||||||
|
FString(
|
||||||
|
FString {
|
||||||
|
range: 107..147,
|
||||||
|
elements: [
|
||||||
|
Expression(
|
||||||
|
FStringExpressionElement {
|
||||||
|
range: 111..144,
|
||||||
|
expression: FString(
|
||||||
|
ExprFString {
|
||||||
|
range: 112..143,
|
||||||
|
value: FStringValue {
|
||||||
|
inner: Single(
|
||||||
|
FString(
|
||||||
|
FString {
|
||||||
|
range: 112..143,
|
||||||
|
elements: [
|
||||||
|
Expression(
|
||||||
|
FStringExpressionElement {
|
||||||
|
range: 116..140,
|
||||||
|
expression: FString(
|
||||||
|
ExprFString {
|
||||||
|
range: 117..139,
|
||||||
|
value: FStringValue {
|
||||||
|
inner: Single(
|
||||||
|
FString(
|
||||||
|
FString {
|
||||||
|
range: 117..139,
|
||||||
|
elements: [
|
||||||
|
Expression(
|
||||||
|
FStringExpressionElement {
|
||||||
|
range: 119..138,
|
||||||
|
expression: StringLiteral(
|
||||||
|
ExprStringLiteral {
|
||||||
|
range: 120..137,
|
||||||
|
value: StringLiteralValue {
|
||||||
|
inner: Single(
|
||||||
|
StringLiteral {
|
||||||
|
range: 120..137,
|
||||||
|
value: "# not a comment",
|
||||||
|
flags: StringLiteralFlags {
|
||||||
|
quote_style: Double,
|
||||||
|
prefix: Empty,
|
||||||
|
triple_quoted: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
debug_text: None,
|
||||||
|
conversion: None,
|
||||||
|
format_spec: None,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
flags: FStringFlags {
|
||||||
|
quote_style: Single,
|
||||||
|
prefix: Regular,
|
||||||
|
triple_quoted: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
debug_text: None,
|
||||||
|
conversion: None,
|
||||||
|
format_spec: None,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
flags: FStringFlags {
|
||||||
|
quote_style: Single,
|
||||||
|
prefix: Regular,
|
||||||
|
triple_quoted: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
debug_text: None,
|
||||||
|
conversion: None,
|
||||||
|
format_spec: None,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
flags: FStringFlags {
|
||||||
|
quote_style: Double,
|
||||||
|
prefix: Regular,
|
||||||
|
triple_quoted: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
Expr(
|
||||||
|
StmtExpr {
|
||||||
|
range: 148..230,
|
||||||
|
value: FString(
|
||||||
|
ExprFString {
|
||||||
|
range: 148..230,
|
||||||
|
value: FStringValue {
|
||||||
|
inner: Single(
|
||||||
|
FString(
|
||||||
|
FString {
|
||||||
|
range: 148..230,
|
||||||
|
elements: [
|
||||||
|
Expression(
|
||||||
|
FStringExpressionElement {
|
||||||
|
range: 152..208,
|
||||||
|
expression: FString(
|
||||||
|
ExprFString {
|
||||||
|
range: 153..207,
|
||||||
|
value: FStringValue {
|
||||||
|
inner: Single(
|
||||||
|
FString(
|
||||||
|
FString {
|
||||||
|
range: 153..207,
|
||||||
|
elements: [
|
||||||
|
Literal(
|
||||||
|
FStringLiteralElement {
|
||||||
|
range: 157..177,
|
||||||
|
value: "# before expression ",
|
||||||
|
},
|
||||||
|
),
|
||||||
|
Expression(
|
||||||
|
FStringExpressionElement {
|
||||||
|
range: 177..204,
|
||||||
|
expression: FString(
|
||||||
|
ExprFString {
|
||||||
|
range: 178..203,
|
||||||
|
value: FStringValue {
|
||||||
|
inner: Single(
|
||||||
|
FString(
|
||||||
|
FString {
|
||||||
|
range: 178..203,
|
||||||
|
elements: [
|
||||||
|
Literal(
|
||||||
|
FStringLiteralElement {
|
||||||
|
range: 180..185,
|
||||||
|
value: "# aro",
|
||||||
|
},
|
||||||
|
),
|
||||||
|
Expression(
|
||||||
|
FStringExpressionElement {
|
||||||
|
range: 185..197,
|
||||||
|
expression: FString(
|
||||||
|
ExprFString {
|
||||||
|
range: 186..196,
|
||||||
|
value: FStringValue {
|
||||||
|
inner: Single(
|
||||||
|
FString(
|
||||||
|
FString {
|
||||||
|
range: 186..196,
|
||||||
|
elements: [
|
||||||
|
Literal(
|
||||||
|
FStringLiteralElement {
|
||||||
|
range: 188..189,
|
||||||
|
value: "#",
|
||||||
|
},
|
||||||
|
),
|
||||||
|
Expression(
|
||||||
|
FStringExpressionElement {
|
||||||
|
range: 189..194,
|
||||||
|
expression: BinOp(
|
||||||
|
ExprBinOp {
|
||||||
|
range: 190..193,
|
||||||
|
left: NumberLiteral(
|
||||||
|
ExprNumberLiteral {
|
||||||
|
range: 190..191,
|
||||||
|
value: Int(
|
||||||
|
1,
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
op: Add,
|
||||||
|
right: NumberLiteral(
|
||||||
|
ExprNumberLiteral {
|
||||||
|
range: 192..193,
|
||||||
|
value: Int(
|
||||||
|
1,
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
debug_text: None,
|
||||||
|
conversion: None,
|
||||||
|
format_spec: None,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
Literal(
|
||||||
|
FStringLiteralElement {
|
||||||
|
range: 194..195,
|
||||||
|
value: "#",
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
flags: FStringFlags {
|
||||||
|
quote_style: Double,
|
||||||
|
prefix: Regular,
|
||||||
|
triple_quoted: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
debug_text: None,
|
||||||
|
conversion: None,
|
||||||
|
format_spec: None,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
Literal(
|
||||||
|
FStringLiteralElement {
|
||||||
|
range: 197..202,
|
||||||
|
value: "und #",
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
flags: FStringFlags {
|
||||||
|
quote_style: Single,
|
||||||
|
prefix: Regular,
|
||||||
|
triple_quoted: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
debug_text: None,
|
||||||
|
conversion: None,
|
||||||
|
format_spec: None,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
flags: FStringFlags {
|
||||||
|
quote_style: Single,
|
||||||
|
prefix: Regular,
|
||||||
|
triple_quoted: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
debug_text: None,
|
||||||
|
conversion: None,
|
||||||
|
format_spec: None,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
Literal(
|
||||||
|
FStringLiteralElement {
|
||||||
|
range: 208..227,
|
||||||
|
value: " # after expression",
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
flags: FStringFlags {
|
||||||
|
quote_style: Double,
|
||||||
|
prefix: Regular,
|
||||||
|
triple_quoted: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
Expr(
|
||||||
|
StmtExpr {
|
||||||
|
range: 231..263,
|
||||||
|
value: FString(
|
||||||
|
ExprFString {
|
||||||
|
range: 231..263,
|
||||||
|
value: FStringValue {
|
||||||
|
inner: Single(
|
||||||
|
FString(
|
||||||
|
FString {
|
||||||
|
range: 231..263,
|
||||||
|
elements: [
|
||||||
|
Literal(
|
||||||
|
FStringLiteralElement {
|
||||||
|
range: 233..254,
|
||||||
|
value: "escape outside of \t ",
|
||||||
|
},
|
||||||
|
),
|
||||||
|
Expression(
|
||||||
|
FStringExpressionElement {
|
||||||
|
range: 254..260,
|
||||||
|
expression: Name(
|
||||||
|
ExprName {
|
||||||
|
range: 255..259,
|
||||||
|
id: Name("expr"),
|
||||||
|
ctx: Load,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
debug_text: None,
|
||||||
|
conversion: None,
|
||||||
|
format_spec: None,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
Literal(
|
||||||
|
FStringLiteralElement {
|
||||||
|
range: 260..262,
|
||||||
|
value: "\n",
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
flags: FStringFlags {
|
||||||
|
quote_style: Double,
|
||||||
|
prefix: Regular,
|
||||||
|
triple_quoted: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
Expr(
|
||||||
|
StmtExpr {
|
||||||
|
range: 264..277,
|
||||||
|
value: FString(
|
||||||
|
ExprFString {
|
||||||
|
range: 264..277,
|
||||||
|
value: FStringValue {
|
||||||
|
inner: Single(
|
||||||
|
FString(
|
||||||
|
FString {
|
||||||
|
range: 264..277,
|
||||||
|
elements: [
|
||||||
|
Literal(
|
||||||
|
FStringLiteralElement {
|
||||||
|
range: 266..276,
|
||||||
|
value: "test\"abcd",
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
flags: FStringFlags {
|
||||||
|
quote_style: Double,
|
||||||
|
prefix: Regular,
|
||||||
|
triple_quoted: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
@ -0,0 +1,584 @@
|
||||||
|
---
|
||||||
|
source: crates/ruff_python_parser/tests/fixtures.rs
|
||||||
|
input_file: crates/ruff_python_parser/resources/inline/ok/pep701_f_string_py312.py
|
||||||
|
---
|
||||||
|
## AST
|
||||||
|
|
||||||
|
```
|
||||||
|
Module(
|
||||||
|
ModModule {
|
||||||
|
range: 0..403,
|
||||||
|
body: [
|
||||||
|
Expr(
|
||||||
|
StmtExpr {
|
||||||
|
range: 44..74,
|
||||||
|
value: FString(
|
||||||
|
ExprFString {
|
||||||
|
range: 44..74,
|
||||||
|
value: FStringValue {
|
||||||
|
inner: Single(
|
||||||
|
FString(
|
||||||
|
FString {
|
||||||
|
range: 44..74,
|
||||||
|
elements: [
|
||||||
|
Literal(
|
||||||
|
FStringLiteralElement {
|
||||||
|
range: 46..58,
|
||||||
|
value: "Magic wand: ",
|
||||||
|
},
|
||||||
|
),
|
||||||
|
Expression(
|
||||||
|
FStringExpressionElement {
|
||||||
|
range: 58..73,
|
||||||
|
expression: Subscript(
|
||||||
|
ExprSubscript {
|
||||||
|
range: 60..71,
|
||||||
|
value: Name(
|
||||||
|
ExprName {
|
||||||
|
range: 60..63,
|
||||||
|
id: Name("bag"),
|
||||||
|
ctx: Load,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
slice: StringLiteral(
|
||||||
|
ExprStringLiteral {
|
||||||
|
range: 64..70,
|
||||||
|
value: StringLiteralValue {
|
||||||
|
inner: Single(
|
||||||
|
StringLiteral {
|
||||||
|
range: 64..70,
|
||||||
|
value: "wand",
|
||||||
|
flags: StringLiteralFlags {
|
||||||
|
quote_style: Single,
|
||||||
|
prefix: Empty,
|
||||||
|
triple_quoted: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
ctx: Load,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
debug_text: None,
|
||||||
|
conversion: None,
|
||||||
|
format_spec: None,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
flags: FStringFlags {
|
||||||
|
quote_style: Single,
|
||||||
|
prefix: Regular,
|
||||||
|
triple_quoted: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
Expr(
|
||||||
|
StmtExpr {
|
||||||
|
range: 95..112,
|
||||||
|
value: FString(
|
||||||
|
ExprFString {
|
||||||
|
range: 95..112,
|
||||||
|
value: FStringValue {
|
||||||
|
inner: Single(
|
||||||
|
FString(
|
||||||
|
FString {
|
||||||
|
range: 95..112,
|
||||||
|
elements: [
|
||||||
|
Expression(
|
||||||
|
FStringExpressionElement {
|
||||||
|
range: 97..111,
|
||||||
|
expression: Call(
|
||||||
|
ExprCall {
|
||||||
|
range: 98..110,
|
||||||
|
func: Attribute(
|
||||||
|
ExprAttribute {
|
||||||
|
range: 98..107,
|
||||||
|
value: StringLiteral(
|
||||||
|
ExprStringLiteral {
|
||||||
|
range: 98..102,
|
||||||
|
value: StringLiteralValue {
|
||||||
|
inner: Single(
|
||||||
|
StringLiteral {
|
||||||
|
range: 98..102,
|
||||||
|
value: "\n",
|
||||||
|
flags: StringLiteralFlags {
|
||||||
|
quote_style: Single,
|
||||||
|
prefix: Empty,
|
||||||
|
triple_quoted: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
attr: Identifier {
|
||||||
|
id: Name("join"),
|
||||||
|
range: 103..107,
|
||||||
|
},
|
||||||
|
ctx: Load,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
arguments: Arguments {
|
||||||
|
range: 107..110,
|
||||||
|
args: [
|
||||||
|
Name(
|
||||||
|
ExprName {
|
||||||
|
range: 108..109,
|
||||||
|
id: Name("a"),
|
||||||
|
ctx: Load,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
keywords: [],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
debug_text: None,
|
||||||
|
conversion: None,
|
||||||
|
format_spec: None,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
flags: FStringFlags {
|
||||||
|
quote_style: Double,
|
||||||
|
prefix: Regular,
|
||||||
|
triple_quoted: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
Expr(
|
||||||
|
StmtExpr {
|
||||||
|
range: 148..220,
|
||||||
|
value: FString(
|
||||||
|
ExprFString {
|
||||||
|
range: 148..220,
|
||||||
|
value: FStringValue {
|
||||||
|
inner: Single(
|
||||||
|
FString(
|
||||||
|
FString {
|
||||||
|
range: 148..220,
|
||||||
|
elements: [
|
||||||
|
Literal(
|
||||||
|
FStringLiteralElement {
|
||||||
|
range: 152..169,
|
||||||
|
value: "A complex trick: ",
|
||||||
|
},
|
||||||
|
),
|
||||||
|
Expression(
|
||||||
|
FStringExpressionElement {
|
||||||
|
range: 169..217,
|
||||||
|
expression: Subscript(
|
||||||
|
ExprSubscript {
|
||||||
|
range: 175..185,
|
||||||
|
value: Name(
|
||||||
|
ExprName {
|
||||||
|
range: 175..178,
|
||||||
|
id: Name("bag"),
|
||||||
|
ctx: Load,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
slice: StringLiteral(
|
||||||
|
ExprStringLiteral {
|
||||||
|
range: 179..184,
|
||||||
|
value: StringLiteralValue {
|
||||||
|
inner: Single(
|
||||||
|
StringLiteral {
|
||||||
|
range: 179..184,
|
||||||
|
value: "bag",
|
||||||
|
flags: StringLiteralFlags {
|
||||||
|
quote_style: Single,
|
||||||
|
prefix: Empty,
|
||||||
|
triple_quoted: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
ctx: Load,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
debug_text: None,
|
||||||
|
conversion: None,
|
||||||
|
format_spec: None,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
flags: FStringFlags {
|
||||||
|
quote_style: Single,
|
||||||
|
prefix: Regular,
|
||||||
|
triple_quoted: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
Expr(
|
||||||
|
StmtExpr {
|
||||||
|
range: 221..254,
|
||||||
|
value: FString(
|
||||||
|
ExprFString {
|
||||||
|
range: 221..254,
|
||||||
|
value: FStringValue {
|
||||||
|
inner: Single(
|
||||||
|
FString(
|
||||||
|
FString {
|
||||||
|
range: 221..254,
|
||||||
|
elements: [
|
||||||
|
Expression(
|
||||||
|
FStringExpressionElement {
|
||||||
|
range: 223..253,
|
||||||
|
expression: FString(
|
||||||
|
ExprFString {
|
||||||
|
range: 224..252,
|
||||||
|
value: FStringValue {
|
||||||
|
inner: Single(
|
||||||
|
FString(
|
||||||
|
FString {
|
||||||
|
range: 224..252,
|
||||||
|
elements: [
|
||||||
|
Expression(
|
||||||
|
FStringExpressionElement {
|
||||||
|
range: 226..251,
|
||||||
|
expression: FString(
|
||||||
|
ExprFString {
|
||||||
|
range: 227..250,
|
||||||
|
value: FStringValue {
|
||||||
|
inner: Single(
|
||||||
|
FString(
|
||||||
|
FString {
|
||||||
|
range: 227..250,
|
||||||
|
elements: [
|
||||||
|
Expression(
|
||||||
|
FStringExpressionElement {
|
||||||
|
range: 229..249,
|
||||||
|
expression: FString(
|
||||||
|
ExprFString {
|
||||||
|
range: 230..248,
|
||||||
|
value: FStringValue {
|
||||||
|
inner: Single(
|
||||||
|
FString(
|
||||||
|
FString {
|
||||||
|
range: 230..248,
|
||||||
|
elements: [
|
||||||
|
Expression(
|
||||||
|
FStringExpressionElement {
|
||||||
|
range: 232..247,
|
||||||
|
expression: FString(
|
||||||
|
ExprFString {
|
||||||
|
range: 233..246,
|
||||||
|
value: FStringValue {
|
||||||
|
inner: Single(
|
||||||
|
FString(
|
||||||
|
FString {
|
||||||
|
range: 233..246,
|
||||||
|
elements: [
|
||||||
|
Expression(
|
||||||
|
FStringExpressionElement {
|
||||||
|
range: 235..245,
|
||||||
|
expression: FString(
|
||||||
|
ExprFString {
|
||||||
|
range: 236..244,
|
||||||
|
value: FStringValue {
|
||||||
|
inner: Single(
|
||||||
|
FString(
|
||||||
|
FString {
|
||||||
|
range: 236..244,
|
||||||
|
elements: [
|
||||||
|
Expression(
|
||||||
|
FStringExpressionElement {
|
||||||
|
range: 238..243,
|
||||||
|
expression: BinOp(
|
||||||
|
ExprBinOp {
|
||||||
|
range: 239..242,
|
||||||
|
left: NumberLiteral(
|
||||||
|
ExprNumberLiteral {
|
||||||
|
range: 239..240,
|
||||||
|
value: Int(
|
||||||
|
1,
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
op: Add,
|
||||||
|
right: NumberLiteral(
|
||||||
|
ExprNumberLiteral {
|
||||||
|
range: 241..242,
|
||||||
|
value: Int(
|
||||||
|
1,
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
debug_text: None,
|
||||||
|
conversion: None,
|
||||||
|
format_spec: None,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
flags: FStringFlags {
|
||||||
|
quote_style: Double,
|
||||||
|
prefix: Regular,
|
||||||
|
triple_quoted: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
debug_text: None,
|
||||||
|
conversion: None,
|
||||||
|
format_spec: None,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
flags: FStringFlags {
|
||||||
|
quote_style: Double,
|
||||||
|
prefix: Regular,
|
||||||
|
triple_quoted: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
debug_text: None,
|
||||||
|
conversion: None,
|
||||||
|
format_spec: None,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
flags: FStringFlags {
|
||||||
|
quote_style: Double,
|
||||||
|
prefix: Regular,
|
||||||
|
triple_quoted: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
debug_text: None,
|
||||||
|
conversion: None,
|
||||||
|
format_spec: None,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
flags: FStringFlags {
|
||||||
|
quote_style: Double,
|
||||||
|
prefix: Regular,
|
||||||
|
triple_quoted: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
debug_text: None,
|
||||||
|
conversion: None,
|
||||||
|
format_spec: None,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
flags: FStringFlags {
|
||||||
|
quote_style: Double,
|
||||||
|
prefix: Regular,
|
||||||
|
triple_quoted: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
debug_text: None,
|
||||||
|
conversion: None,
|
||||||
|
format_spec: None,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
flags: FStringFlags {
|
||||||
|
quote_style: Double,
|
||||||
|
prefix: Regular,
|
||||||
|
triple_quoted: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
Expr(
|
||||||
|
StmtExpr {
|
||||||
|
range: 276..310,
|
||||||
|
value: FString(
|
||||||
|
ExprFString {
|
||||||
|
range: 276..310,
|
||||||
|
value: FStringValue {
|
||||||
|
inner: Single(
|
||||||
|
FString(
|
||||||
|
FString {
|
||||||
|
range: 276..310,
|
||||||
|
elements: [
|
||||||
|
Expression(
|
||||||
|
FStringExpressionElement {
|
||||||
|
range: 278..303,
|
||||||
|
expression: FString(
|
||||||
|
ExprFString {
|
||||||
|
range: 279..302,
|
||||||
|
value: FStringValue {
|
||||||
|
inner: Single(
|
||||||
|
FString(
|
||||||
|
FString {
|
||||||
|
range: 279..302,
|
||||||
|
elements: [
|
||||||
|
Expression(
|
||||||
|
FStringExpressionElement {
|
||||||
|
range: 283..293,
|
||||||
|
expression: StringLiteral(
|
||||||
|
ExprStringLiteral {
|
||||||
|
range: 284..292,
|
||||||
|
value: StringLiteralValue {
|
||||||
|
inner: Single(
|
||||||
|
StringLiteral {
|
||||||
|
range: 284..292,
|
||||||
|
value: "nested",
|
||||||
|
flags: StringLiteralFlags {
|
||||||
|
quote_style: Double,
|
||||||
|
prefix: Empty,
|
||||||
|
triple_quoted: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
debug_text: None,
|
||||||
|
conversion: None,
|
||||||
|
format_spec: None,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
Literal(
|
||||||
|
FStringLiteralElement {
|
||||||
|
range: 293..299,
|
||||||
|
value: " inner",
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
flags: FStringFlags {
|
||||||
|
quote_style: Single,
|
||||||
|
prefix: Regular,
|
||||||
|
triple_quoted: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
debug_text: None,
|
||||||
|
conversion: None,
|
||||||
|
format_spec: None,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
Literal(
|
||||||
|
FStringLiteralElement {
|
||||||
|
range: 303..309,
|
||||||
|
value: " outer",
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
flags: FStringFlags {
|
||||||
|
quote_style: Double,
|
||||||
|
prefix: Regular,
|
||||||
|
triple_quoted: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
Expr(
|
||||||
|
StmtExpr {
|
||||||
|
range: 336..359,
|
||||||
|
value: FString(
|
||||||
|
ExprFString {
|
||||||
|
range: 336..359,
|
||||||
|
value: FStringValue {
|
||||||
|
inner: Single(
|
||||||
|
FString(
|
||||||
|
FString {
|
||||||
|
range: 336..359,
|
||||||
|
elements: [
|
||||||
|
Literal(
|
||||||
|
FStringLiteralElement {
|
||||||
|
range: 338..343,
|
||||||
|
value: "test ",
|
||||||
|
},
|
||||||
|
),
|
||||||
|
Expression(
|
||||||
|
FStringExpressionElement {
|
||||||
|
range: 343..353,
|
||||||
|
expression: Name(
|
||||||
|
ExprName {
|
||||||
|
range: 344..345,
|
||||||
|
id: Name("a"),
|
||||||
|
ctx: Load,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
debug_text: None,
|
||||||
|
conversion: None,
|
||||||
|
format_spec: None,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
Literal(
|
||||||
|
FStringLiteralElement {
|
||||||
|
range: 353..358,
|
||||||
|
value: " more",
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
flags: FStringFlags {
|
||||||
|
quote_style: Double,
|
||||||
|
prefix: Regular,
|
||||||
|
triple_quoted: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
)
|
||||||
|
```
|
||||||
Loading…
Reference in New Issue