mirror of
https://github.com/astral-sh/ruff.git
synced 2025-09-29 13:24:57 +00:00
[syntax-errors] Raise unsupported syntax error for template strings prior to Python 3.14 (#18664)
Closes #18662 One question is whether we would like the range to exclude the quotes?
This commit is contained in:
parent
793ff9bdbc
commit
1889a5e6eb
5 changed files with 459 additions and 2 deletions
|
@ -0,0 +1,6 @@
|
||||||
|
# parse_options: {"target-version": "3.13"}
|
||||||
|
t"{hey}"
|
||||||
|
t'{there}'
|
||||||
|
t"""what's
|
||||||
|
happening?"""
|
||||||
|
"implicitly"t"concatenated"
|
|
@ -0,0 +1,6 @@
|
||||||
|
# parse_options: {"target-version": "3.14"}
|
||||||
|
t"{hey}"
|
||||||
|
t'{there}'
|
||||||
|
t"""what's
|
||||||
|
happening?"""
|
||||||
|
"implicitly"t"concatenated"
|
|
@ -1250,10 +1250,30 @@ impl<'src> Parser<'src> {
|
||||||
.into(),
|
.into(),
|
||||||
));
|
));
|
||||||
} else if self.at(TokenKind::TStringStart) {
|
} else if self.at(TokenKind::TStringStart) {
|
||||||
strings.push(StringType::TString(
|
// test_ok template_strings_py314
|
||||||
|
// # parse_options: {"target-version": "3.14"}
|
||||||
|
// t"{hey}"
|
||||||
|
// t'{there}'
|
||||||
|
// t"""what's
|
||||||
|
// happening?"""
|
||||||
|
// "implicitly"t"concatenated"
|
||||||
|
|
||||||
|
// test_err template_strings_py313
|
||||||
|
// # parse_options: {"target-version": "3.13"}
|
||||||
|
// t"{hey}"
|
||||||
|
// t'{there}'
|
||||||
|
// t"""what's
|
||||||
|
// happening?"""
|
||||||
|
// "implicitly"t"concatenated"
|
||||||
|
let string_type = StringType::TString(
|
||||||
self.parse_interpolated_string(InterpolatedStringKind::TString)
|
self.parse_interpolated_string(InterpolatedStringKind::TString)
|
||||||
.into(),
|
.into(),
|
||||||
));
|
);
|
||||||
|
self.add_unsupported_syntax_error(
|
||||||
|
UnsupportedSyntaxErrorKind::TemplateStrings,
|
||||||
|
string_type.range(),
|
||||||
|
);
|
||||||
|
strings.push(string_type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,231 @@
|
||||||
|
---
|
||||||
|
source: crates/ruff_python_parser/tests/fixtures.rs
|
||||||
|
input_file: crates/ruff_python_parser/resources/inline/err/template_strings_py313.py
|
||||||
|
---
|
||||||
|
## AST
|
||||||
|
|
||||||
|
```
|
||||||
|
Module(
|
||||||
|
ModModule {
|
||||||
|
node_index: AtomicNodeIndex(..),
|
||||||
|
range: 0..117,
|
||||||
|
body: [
|
||||||
|
Expr(
|
||||||
|
StmtExpr {
|
||||||
|
node_index: AtomicNodeIndex(..),
|
||||||
|
range: 44..52,
|
||||||
|
value: TString(
|
||||||
|
ExprTString {
|
||||||
|
node_index: AtomicNodeIndex(..),
|
||||||
|
range: 44..52,
|
||||||
|
value: TStringValue {
|
||||||
|
inner: Single(
|
||||||
|
TString(
|
||||||
|
TString {
|
||||||
|
range: 44..52,
|
||||||
|
node_index: AtomicNodeIndex(..),
|
||||||
|
elements: [
|
||||||
|
Interpolation(
|
||||||
|
InterpolatedElement {
|
||||||
|
range: 46..51,
|
||||||
|
node_index: AtomicNodeIndex(..),
|
||||||
|
expression: Name(
|
||||||
|
ExprName {
|
||||||
|
node_index: AtomicNodeIndex(..),
|
||||||
|
range: 47..50,
|
||||||
|
id: Name("hey"),
|
||||||
|
ctx: Load,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
debug_text: None,
|
||||||
|
conversion: None,
|
||||||
|
format_spec: None,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
flags: TStringFlags {
|
||||||
|
quote_style: Double,
|
||||||
|
prefix: Regular,
|
||||||
|
triple_quoted: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
Expr(
|
||||||
|
StmtExpr {
|
||||||
|
node_index: AtomicNodeIndex(..),
|
||||||
|
range: 53..63,
|
||||||
|
value: TString(
|
||||||
|
ExprTString {
|
||||||
|
node_index: AtomicNodeIndex(..),
|
||||||
|
range: 53..63,
|
||||||
|
value: TStringValue {
|
||||||
|
inner: Single(
|
||||||
|
TString(
|
||||||
|
TString {
|
||||||
|
range: 53..63,
|
||||||
|
node_index: AtomicNodeIndex(..),
|
||||||
|
elements: [
|
||||||
|
Interpolation(
|
||||||
|
InterpolatedElement {
|
||||||
|
range: 55..62,
|
||||||
|
node_index: AtomicNodeIndex(..),
|
||||||
|
expression: Name(
|
||||||
|
ExprName {
|
||||||
|
node_index: AtomicNodeIndex(..),
|
||||||
|
range: 56..61,
|
||||||
|
id: Name("there"),
|
||||||
|
ctx: Load,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
debug_text: None,
|
||||||
|
conversion: None,
|
||||||
|
format_spec: None,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
flags: TStringFlags {
|
||||||
|
quote_style: Single,
|
||||||
|
prefix: Regular,
|
||||||
|
triple_quoted: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
Expr(
|
||||||
|
StmtExpr {
|
||||||
|
node_index: AtomicNodeIndex(..),
|
||||||
|
range: 64..88,
|
||||||
|
value: TString(
|
||||||
|
ExprTString {
|
||||||
|
node_index: AtomicNodeIndex(..),
|
||||||
|
range: 64..88,
|
||||||
|
value: TStringValue {
|
||||||
|
inner: Single(
|
||||||
|
TString(
|
||||||
|
TString {
|
||||||
|
range: 64..88,
|
||||||
|
node_index: AtomicNodeIndex(..),
|
||||||
|
elements: [
|
||||||
|
Literal(
|
||||||
|
InterpolatedStringLiteralElement {
|
||||||
|
range: 68..85,
|
||||||
|
node_index: AtomicNodeIndex(..),
|
||||||
|
value: "what's\nhappening?",
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
flags: TStringFlags {
|
||||||
|
quote_style: Double,
|
||||||
|
prefix: Regular,
|
||||||
|
triple_quoted: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
Expr(
|
||||||
|
StmtExpr {
|
||||||
|
node_index: AtomicNodeIndex(..),
|
||||||
|
range: 89..116,
|
||||||
|
value: TString(
|
||||||
|
ExprTString {
|
||||||
|
node_index: AtomicNodeIndex(..),
|
||||||
|
range: 89..116,
|
||||||
|
value: TStringValue {
|
||||||
|
inner: Concatenated(
|
||||||
|
[
|
||||||
|
Literal(
|
||||||
|
StringLiteral {
|
||||||
|
range: 89..101,
|
||||||
|
node_index: AtomicNodeIndex(..),
|
||||||
|
value: "implicitly",
|
||||||
|
flags: StringLiteralFlags {
|
||||||
|
quote_style: Double,
|
||||||
|
prefix: Empty,
|
||||||
|
triple_quoted: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
TString(
|
||||||
|
TString {
|
||||||
|
range: 101..116,
|
||||||
|
node_index: AtomicNodeIndex(..),
|
||||||
|
elements: [
|
||||||
|
Literal(
|
||||||
|
InterpolatedStringLiteralElement {
|
||||||
|
range: 103..115,
|
||||||
|
node_index: AtomicNodeIndex(..),
|
||||||
|
value: "concatenated",
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
flags: TStringFlags {
|
||||||
|
quote_style: Double,
|
||||||
|
prefix: Regular,
|
||||||
|
triple_quoted: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
)
|
||||||
|
```
|
||||||
|
## Unsupported Syntax Errors
|
||||||
|
|
||||||
|
|
|
||||||
|
1 | # parse_options: {"target-version": "3.13"}
|
||||||
|
2 | t"{hey}"
|
||||||
|
| ^^^^^^^^ Syntax Error: Cannot use t-strings on Python 3.13 (syntax was added in Python 3.14)
|
||||||
|
3 | t'{there}'
|
||||||
|
4 | t"""what's
|
||||||
|
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
1 | # parse_options: {"target-version": "3.13"}
|
||||||
|
2 | t"{hey}"
|
||||||
|
3 | t'{there}'
|
||||||
|
| ^^^^^^^^^^ Syntax Error: Cannot use t-strings on Python 3.13 (syntax was added in Python 3.14)
|
||||||
|
4 | t"""what's
|
||||||
|
5 | happening?"""
|
||||||
|
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
2 | t"{hey}"
|
||||||
|
3 | t'{there}'
|
||||||
|
4 | / t"""what's
|
||||||
|
5 | | happening?"""
|
||||||
|
| |_____________^ Syntax Error: Cannot use t-strings on Python 3.13 (syntax was added in Python 3.14)
|
||||||
|
6 | "implicitly"t"concatenated"
|
||||||
|
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
4 | t"""what's
|
||||||
|
5 | happening?"""
|
||||||
|
6 | "implicitly"t"concatenated"
|
||||||
|
| ^^^^^^^^^^^^^^^ Syntax Error: Cannot use t-strings on Python 3.13 (syntax was added in Python 3.14)
|
||||||
|
|
|
|
@ -0,0 +1,194 @@
|
||||||
|
---
|
||||||
|
source: crates/ruff_python_parser/tests/fixtures.rs
|
||||||
|
input_file: crates/ruff_python_parser/resources/inline/ok/template_strings_py314.py
|
||||||
|
---
|
||||||
|
## AST
|
||||||
|
|
||||||
|
```
|
||||||
|
Module(
|
||||||
|
ModModule {
|
||||||
|
node_index: AtomicNodeIndex(..),
|
||||||
|
range: 0..117,
|
||||||
|
body: [
|
||||||
|
Expr(
|
||||||
|
StmtExpr {
|
||||||
|
node_index: AtomicNodeIndex(..),
|
||||||
|
range: 44..52,
|
||||||
|
value: TString(
|
||||||
|
ExprTString {
|
||||||
|
node_index: AtomicNodeIndex(..),
|
||||||
|
range: 44..52,
|
||||||
|
value: TStringValue {
|
||||||
|
inner: Single(
|
||||||
|
TString(
|
||||||
|
TString {
|
||||||
|
range: 44..52,
|
||||||
|
node_index: AtomicNodeIndex(..),
|
||||||
|
elements: [
|
||||||
|
Interpolation(
|
||||||
|
InterpolatedElement {
|
||||||
|
range: 46..51,
|
||||||
|
node_index: AtomicNodeIndex(..),
|
||||||
|
expression: Name(
|
||||||
|
ExprName {
|
||||||
|
node_index: AtomicNodeIndex(..),
|
||||||
|
range: 47..50,
|
||||||
|
id: Name("hey"),
|
||||||
|
ctx: Load,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
debug_text: None,
|
||||||
|
conversion: None,
|
||||||
|
format_spec: None,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
flags: TStringFlags {
|
||||||
|
quote_style: Double,
|
||||||
|
prefix: Regular,
|
||||||
|
triple_quoted: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
Expr(
|
||||||
|
StmtExpr {
|
||||||
|
node_index: AtomicNodeIndex(..),
|
||||||
|
range: 53..63,
|
||||||
|
value: TString(
|
||||||
|
ExprTString {
|
||||||
|
node_index: AtomicNodeIndex(..),
|
||||||
|
range: 53..63,
|
||||||
|
value: TStringValue {
|
||||||
|
inner: Single(
|
||||||
|
TString(
|
||||||
|
TString {
|
||||||
|
range: 53..63,
|
||||||
|
node_index: AtomicNodeIndex(..),
|
||||||
|
elements: [
|
||||||
|
Interpolation(
|
||||||
|
InterpolatedElement {
|
||||||
|
range: 55..62,
|
||||||
|
node_index: AtomicNodeIndex(..),
|
||||||
|
expression: Name(
|
||||||
|
ExprName {
|
||||||
|
node_index: AtomicNodeIndex(..),
|
||||||
|
range: 56..61,
|
||||||
|
id: Name("there"),
|
||||||
|
ctx: Load,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
debug_text: None,
|
||||||
|
conversion: None,
|
||||||
|
format_spec: None,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
flags: TStringFlags {
|
||||||
|
quote_style: Single,
|
||||||
|
prefix: Regular,
|
||||||
|
triple_quoted: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
Expr(
|
||||||
|
StmtExpr {
|
||||||
|
node_index: AtomicNodeIndex(..),
|
||||||
|
range: 64..88,
|
||||||
|
value: TString(
|
||||||
|
ExprTString {
|
||||||
|
node_index: AtomicNodeIndex(..),
|
||||||
|
range: 64..88,
|
||||||
|
value: TStringValue {
|
||||||
|
inner: Single(
|
||||||
|
TString(
|
||||||
|
TString {
|
||||||
|
range: 64..88,
|
||||||
|
node_index: AtomicNodeIndex(..),
|
||||||
|
elements: [
|
||||||
|
Literal(
|
||||||
|
InterpolatedStringLiteralElement {
|
||||||
|
range: 68..85,
|
||||||
|
node_index: AtomicNodeIndex(..),
|
||||||
|
value: "what's\nhappening?",
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
flags: TStringFlags {
|
||||||
|
quote_style: Double,
|
||||||
|
prefix: Regular,
|
||||||
|
triple_quoted: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
Expr(
|
||||||
|
StmtExpr {
|
||||||
|
node_index: AtomicNodeIndex(..),
|
||||||
|
range: 89..116,
|
||||||
|
value: TString(
|
||||||
|
ExprTString {
|
||||||
|
node_index: AtomicNodeIndex(..),
|
||||||
|
range: 89..116,
|
||||||
|
value: TStringValue {
|
||||||
|
inner: Concatenated(
|
||||||
|
[
|
||||||
|
Literal(
|
||||||
|
StringLiteral {
|
||||||
|
range: 89..101,
|
||||||
|
node_index: AtomicNodeIndex(..),
|
||||||
|
value: "implicitly",
|
||||||
|
flags: StringLiteralFlags {
|
||||||
|
quote_style: Double,
|
||||||
|
prefix: Empty,
|
||||||
|
triple_quoted: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
TString(
|
||||||
|
TString {
|
||||||
|
range: 101..116,
|
||||||
|
node_index: AtomicNodeIndex(..),
|
||||||
|
elements: [
|
||||||
|
Literal(
|
||||||
|
InterpolatedStringLiteralElement {
|
||||||
|
range: 103..115,
|
||||||
|
node_index: AtomicNodeIndex(..),
|
||||||
|
value: "concatenated",
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
flags: TStringFlags {
|
||||||
|
quote_style: Double,
|
||||||
|
prefix: Regular,
|
||||||
|
triple_quoted: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
)
|
||||||
|
```
|
Loading…
Add table
Add a link
Reference in a new issue