Disallow implicit concatenation of t-strings and other string types (#19485)
Some checks are pending
CI / Determine changes (push) Waiting to run
CI / cargo fmt (push) Waiting to run
CI / cargo clippy (push) Blocked by required conditions
CI / cargo test (linux) (push) Blocked by required conditions
CI / cargo test (linux, release) (push) Blocked by required conditions
CI / cargo test (windows) (push) Blocked by required conditions
CI / cargo test (wasm) (push) Blocked by required conditions
CI / cargo build (release) (push) Waiting to run
CI / cargo build (msrv) (push) Blocked by required conditions
CI / cargo fuzz build (push) Blocked by required conditions
CI / fuzz parser (push) Blocked by required conditions
CI / test scripts (push) Blocked by required conditions
CI / ecosystem (push) Blocked by required conditions
CI / Fuzz for new ty panics (push) Blocked by required conditions
CI / cargo shear (push) Blocked by required conditions
CI / python package (push) Waiting to run
CI / pre-commit (push) Waiting to run
CI / mkdocs (push) Waiting to run
CI / formatter instabilities and black similarity (push) Blocked by required conditions
CI / test ruff-lsp (push) Blocked by required conditions
CI / check playground (push) Blocked by required conditions
CI / benchmarks-instrumented (push) Blocked by required conditions
CI / benchmarks-walltime (push) Blocked by required conditions
[ty Playground] Release / publish (push) Waiting to run

As of [this cpython PR](https://github.com/python/cpython/pull/135996),
it is not allowed to concatenate t-strings with non-t-strings,
implicitly or explicitly. Expressions such as `"foo" t"{bar}"` are now
syntax errors.

This PR updates some AST nodes and parsing to reflect this change.

The structural change is that `TStringPart` is no longer needed, since,
as in the case of `BytesStringLiteral`, the only possibilities are that
we have a single `TString` or a vector of such (representing an implicit
concatenation of t-strings). This removes a level of nesting from many
AST expressions (which is what all the snapshot changes reflect), and
simplifies some logic in the implementation of visitors, for example.

The other change of note is in the parser. When we meet an implicit
concatenation of string-like literals, we now count the number of
t-string literals. If these do not exhaust the total number of
implicitly concatenated pieces, then we emit a syntax error. To recover
from this syntax error, we encode any t-string pieces as _invalid_
string literals (which means we flag them as invalid, record their
range, and record the value as `""`). Note that if at least one of the
pieces is an f-string we prefer to parse the entire string as an
f-string; otherwise we parse it as a string.

This logic is exactly the same as how we currently treat
`BytesStringLiteral` parsing and error recovery - and carries with it
the same pros and cons.

Finally, note that I have not implemented any changes in the
implementation of the formatter. As far as I can tell, none are needed.
I did change a few of the fixtures so that we are always concatenating
t-strings with t-strings.
This commit is contained in:
Dylan 2025-07-27 07:41:03 -05:00 committed by GitHub
parent df5eba7583
commit 008bbfdf5a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
75 changed files with 4509 additions and 6294 deletions

View file

@ -66,36 +66,34 @@ Module(
range: 10..19,
value: TStringValue {
inner: Single(
TString(
TString {
range: 10..19,
node_index: AtomicNodeIndex(..),
elements: [
Interpolation(
InterpolatedElement {
range: 12..18,
node_index: AtomicNodeIndex(..),
expression: Name(
ExprName {
node_index: AtomicNodeIndex(..),
range: 13..14,
id: Name("x"),
ctx: Load,
},
),
debug_text: None,
conversion: Str,
format_spec: None,
},
),
],
flags: TStringFlags {
quote_style: Double,
prefix: Regular,
triple_quoted: false,
},
TString {
range: 10..19,
node_index: AtomicNodeIndex(..),
elements: [
Interpolation(
InterpolatedElement {
range: 12..18,
node_index: AtomicNodeIndex(..),
expression: Name(
ExprName {
node_index: AtomicNodeIndex(..),
range: 13..14,
id: Name("x"),
ctx: Load,
},
),
debug_text: None,
conversion: Str,
format_spec: None,
},
),
],
flags: TStringFlags {
quote_style: Double,
prefix: Regular,
triple_quoted: false,
},
),
},
),
},
},

View file

@ -20,36 +20,34 @@ Module(
range: 44..49,
value: TStringValue {
inner: Single(
TString(
TString {
range: 44..49,
node_index: AtomicNodeIndex(..),
elements: [
Interpolation(
InterpolatedElement {
range: 46..48,
node_index: AtomicNodeIndex(..),
expression: Name(
ExprName {
node_index: AtomicNodeIndex(..),
range: 47..47,
id: Name(""),
ctx: Invalid,
},
),
debug_text: None,
conversion: None,
format_spec: None,
},
),
],
flags: TStringFlags {
quote_style: Double,
prefix: Regular,
triple_quoted: false,
},
TString {
range: 44..49,
node_index: AtomicNodeIndex(..),
elements: [
Interpolation(
InterpolatedElement {
range: 46..48,
node_index: AtomicNodeIndex(..),
expression: Name(
ExprName {
node_index: AtomicNodeIndex(..),
range: 47..47,
id: Name(""),
ctx: Invalid,
},
),
debug_text: None,
conversion: None,
format_spec: None,
},
),
],
flags: TStringFlags {
quote_style: Double,
prefix: Regular,
triple_quoted: false,
},
),
},
),
},
},
@ -66,36 +64,34 @@ Module(
range: 50..57,
value: TStringValue {
inner: Single(
TString(
TString {
range: 50..57,
node_index: AtomicNodeIndex(..),
elements: [
Interpolation(
InterpolatedElement {
range: 52..56,
node_index: AtomicNodeIndex(..),
expression: Name(
ExprName {
node_index: AtomicNodeIndex(..),
range: 53..53,
id: Name(""),
ctx: Invalid,
},
),
debug_text: None,
conversion: None,
format_spec: None,
},
),
],
flags: TStringFlags {
quote_style: Double,
prefix: Regular,
triple_quoted: false,
},
TString {
range: 50..57,
node_index: AtomicNodeIndex(..),
elements: [
Interpolation(
InterpolatedElement {
range: 52..56,
node_index: AtomicNodeIndex(..),
expression: Name(
ExprName {
node_index: AtomicNodeIndex(..),
range: 53..53,
id: Name(""),
ctx: Invalid,
},
),
debug_text: None,
conversion: None,
format_spec: None,
},
),
],
flags: TStringFlags {
quote_style: Double,
prefix: Regular,
triple_quoted: false,
},
),
},
),
},
},

View file

@ -20,36 +20,34 @@ Module(
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..48,
id: Name("x"),
ctx: Load,
},
),
debug_text: None,
conversion: None,
format_spec: None,
},
),
],
flags: TStringFlags {
quote_style: Double,
prefix: Regular,
triple_quoted: false,
},
TString {
range: 44..52,
node_index: AtomicNodeIndex(..),
elements: [
Interpolation(
InterpolatedElement {
range: 46..51,
node_index: AtomicNodeIndex(..),
expression: Name(
ExprName {
node_index: AtomicNodeIndex(..),
range: 47..48,
id: Name("x"),
ctx: Load,
},
),
debug_text: None,
conversion: None,
format_spec: None,
},
),
],
flags: TStringFlags {
quote_style: Double,
prefix: Regular,
triple_quoted: false,
},
),
},
),
},
},

View file

@ -20,36 +20,34 @@ Module(
range: 44..54,
value: TStringValue {
inner: Single(
TString(
TString {
range: 44..54,
node_index: AtomicNodeIndex(..),
elements: [
Interpolation(
InterpolatedElement {
range: 46..53,
node_index: AtomicNodeIndex(..),
expression: Name(
ExprName {
node_index: AtomicNodeIndex(..),
range: 47..48,
id: Name("x"),
ctx: Load,
},
),
debug_text: None,
conversion: None,
format_spec: None,
},
),
],
flags: TStringFlags {
quote_style: Double,
prefix: Regular,
triple_quoted: false,
},
TString {
range: 44..54,
node_index: AtomicNodeIndex(..),
elements: [
Interpolation(
InterpolatedElement {
range: 46..53,
node_index: AtomicNodeIndex(..),
expression: Name(
ExprName {
node_index: AtomicNodeIndex(..),
range: 47..48,
id: Name("x"),
ctx: Load,
},
),
debug_text: None,
conversion: None,
format_spec: None,
},
),
],
flags: TStringFlags {
quote_style: Double,
prefix: Regular,
triple_quoted: false,
},
),
},
),
},
},
@ -66,36 +64,34 @@ Module(
range: 55..65,
value: TStringValue {
inner: Single(
TString(
TString {
range: 55..65,
node_index: AtomicNodeIndex(..),
elements: [
Interpolation(
InterpolatedElement {
range: 57..64,
node_index: AtomicNodeIndex(..),
expression: Name(
ExprName {
node_index: AtomicNodeIndex(..),
range: 58..59,
id: Name("x"),
ctx: Load,
},
),
debug_text: None,
conversion: None,
format_spec: None,
},
),
],
flags: TStringFlags {
quote_style: Double,
prefix: Regular,
triple_quoted: false,
},
TString {
range: 55..65,
node_index: AtomicNodeIndex(..),
elements: [
Interpolation(
InterpolatedElement {
range: 57..64,
node_index: AtomicNodeIndex(..),
expression: Name(
ExprName {
node_index: AtomicNodeIndex(..),
range: 58..59,
id: Name("x"),
ctx: Load,
},
),
debug_text: None,
conversion: None,
format_spec: None,
},
),
],
flags: TStringFlags {
quote_style: Double,
prefix: Regular,
triple_quoted: false,
},
),
},
),
},
},

View file

@ -20,43 +20,41 @@ Module(
range: 121..127,
value: TStringValue {
inner: Single(
TString(
TString {
range: 121..127,
node_index: AtomicNodeIndex(..),
elements: [
Interpolation(
InterpolatedElement {
range: 123..126,
node_index: AtomicNodeIndex(..),
expression: Starred(
ExprStarred {
node_index: AtomicNodeIndex(..),
range: 124..125,
value: Name(
ExprName {
node_index: AtomicNodeIndex(..),
range: 125..125,
id: Name(""),
ctx: Invalid,
},
),
ctx: Load,
},
),
debug_text: None,
conversion: None,
format_spec: None,
},
),
],
flags: TStringFlags {
quote_style: Double,
prefix: Regular,
triple_quoted: false,
},
TString {
range: 121..127,
node_index: AtomicNodeIndex(..),
elements: [
Interpolation(
InterpolatedElement {
range: 123..126,
node_index: AtomicNodeIndex(..),
expression: Starred(
ExprStarred {
node_index: AtomicNodeIndex(..),
range: 124..125,
value: Name(
ExprName {
node_index: AtomicNodeIndex(..),
range: 125..125,
id: Name(""),
ctx: Invalid,
},
),
ctx: Load,
},
),
debug_text: None,
conversion: None,
format_spec: None,
},
),
],
flags: TStringFlags {
quote_style: Double,
prefix: Regular,
triple_quoted: false,
},
),
},
),
},
},
@ -73,60 +71,58 @@ Module(
range: 128..141,
value: TStringValue {
inner: Single(
TString(
TString {
range: 128..141,
node_index: AtomicNodeIndex(..),
elements: [
Interpolation(
InterpolatedElement {
range: 130..140,
node_index: AtomicNodeIndex(..),
expression: Starred(
ExprStarred {
node_index: AtomicNodeIndex(..),
range: 131..139,
value: BoolOp(
ExprBoolOp {
node_index: AtomicNodeIndex(..),
range: 132..139,
op: And,
values: [
Name(
ExprName {
node_index: AtomicNodeIndex(..),
range: 132..133,
id: Name("x"),
ctx: Load,
},
),
Name(
ExprName {
node_index: AtomicNodeIndex(..),
range: 138..139,
id: Name("y"),
ctx: Load,
},
),
],
},
),
ctx: Load,
},
),
debug_text: None,
conversion: None,
format_spec: None,
},
),
],
flags: TStringFlags {
quote_style: Double,
prefix: Regular,
triple_quoted: false,
},
TString {
range: 128..141,
node_index: AtomicNodeIndex(..),
elements: [
Interpolation(
InterpolatedElement {
range: 130..140,
node_index: AtomicNodeIndex(..),
expression: Starred(
ExprStarred {
node_index: AtomicNodeIndex(..),
range: 131..139,
value: BoolOp(
ExprBoolOp {
node_index: AtomicNodeIndex(..),
range: 132..139,
op: And,
values: [
Name(
ExprName {
node_index: AtomicNodeIndex(..),
range: 132..133,
id: Name("x"),
ctx: Load,
},
),
Name(
ExprName {
node_index: AtomicNodeIndex(..),
range: 138..139,
id: Name("y"),
ctx: Load,
},
),
],
},
),
ctx: Load,
},
),
debug_text: None,
conversion: None,
format_spec: None,
},
),
],
flags: TStringFlags {
quote_style: Double,
prefix: Regular,
triple_quoted: false,
},
),
},
),
},
},
@ -143,51 +139,49 @@ Module(
range: 142..155,
value: TStringValue {
inner: Single(
TString(
TString {
range: 142..155,
node_index: AtomicNodeIndex(..),
elements: [
Interpolation(
InterpolatedElement {
range: 144..154,
node_index: AtomicNodeIndex(..),
expression: Starred(
ExprStarred {
node_index: AtomicNodeIndex(..),
range: 145..153,
value: Yield(
ExprYield {
node_index: AtomicNodeIndex(..),
range: 146..153,
value: Some(
Name(
ExprName {
node_index: AtomicNodeIndex(..),
range: 152..153,
id: Name("x"),
ctx: Load,
},
),
TString {
range: 142..155,
node_index: AtomicNodeIndex(..),
elements: [
Interpolation(
InterpolatedElement {
range: 144..154,
node_index: AtomicNodeIndex(..),
expression: Starred(
ExprStarred {
node_index: AtomicNodeIndex(..),
range: 145..153,
value: Yield(
ExprYield {
node_index: AtomicNodeIndex(..),
range: 146..153,
value: Some(
Name(
ExprName {
node_index: AtomicNodeIndex(..),
range: 152..153,
id: Name("x"),
ctx: Load,
},
),
},
),
ctx: Load,
},
),
debug_text: None,
conversion: None,
format_spec: None,
},
),
],
flags: TStringFlags {
quote_style: Double,
prefix: Regular,
triple_quoted: false,
},
),
},
),
ctx: Load,
},
),
debug_text: None,
conversion: None,
format_spec: None,
},
),
],
flags: TStringFlags {
quote_style: Double,
prefix: Regular,
triple_quoted: false,
},
),
},
),
},
},

View file

@ -20,78 +20,76 @@ Module(
range: 44..60,
value: TStringValue {
inner: Single(
TString(
TString {
range: 44..60,
node_index: AtomicNodeIndex(..),
elements: [
Interpolation(
InterpolatedElement {
range: 46..56,
node_index: AtomicNodeIndex(..),
expression: Lambda(
ExprLambda {
node_index: AtomicNodeIndex(..),
range: 47..56,
parameters: Some(
Parameters {
range: 54..55,
node_index: AtomicNodeIndex(
0,
),
posonlyargs: [],
args: [
ParameterWithDefault {
TString {
range: 44..60,
node_index: AtomicNodeIndex(..),
elements: [
Interpolation(
InterpolatedElement {
range: 46..56,
node_index: AtomicNodeIndex(..),
expression: Lambda(
ExprLambda {
node_index: AtomicNodeIndex(..),
range: 47..56,
parameters: Some(
Parameters {
range: 54..55,
node_index: AtomicNodeIndex(
0,
),
posonlyargs: [],
args: [
ParameterWithDefault {
range: 54..55,
node_index: AtomicNodeIndex(..),
parameter: Parameter {
range: 54..55,
node_index: AtomicNodeIndex(..),
parameter: Parameter {
name: Identifier {
id: Name("x"),
range: 54..55,
node_index: AtomicNodeIndex(..),
name: Identifier {
id: Name("x"),
range: 54..55,
node_index: AtomicNodeIndex(..),
},
annotation: None,
},
default: None,
annotation: None,
},
],
vararg: None,
kwonlyargs: [],
kwarg: None,
},
),
body: Name(
ExprName {
node_index: AtomicNodeIndex(..),
range: 56..56,
id: Name(""),
ctx: Invalid,
},
),
},
),
debug_text: None,
conversion: None,
format_spec: None,
},
),
Literal(
InterpolatedStringLiteralElement {
range: 56..58,
node_index: AtomicNodeIndex(..),
value: " x",
},
),
],
flags: TStringFlags {
quote_style: Double,
prefix: Regular,
triple_quoted: false,
},
default: None,
},
],
vararg: None,
kwonlyargs: [],
kwarg: None,
},
),
body: Name(
ExprName {
node_index: AtomicNodeIndex(..),
range: 56..56,
id: Name(""),
ctx: Invalid,
},
),
},
),
debug_text: None,
conversion: None,
format_spec: None,
},
),
Literal(
InterpolatedStringLiteralElement {
range: 56..58,
node_index: AtomicNodeIndex(..),
value: " x",
},
),
],
flags: TStringFlags {
quote_style: Double,
prefix: Regular,
triple_quoted: false,
},
),
},
),
},
},

View file

@ -20,36 +20,34 @@ Module(
range: 44..48,
value: TStringValue {
inner: Single(
TString(
TString {
range: 44..48,
node_index: AtomicNodeIndex(..),
elements: [
Interpolation(
InterpolatedElement {
range: 46..47,
node_index: AtomicNodeIndex(..),
expression: Name(
ExprName {
node_index: AtomicNodeIndex(..),
range: 47..47,
id: Name(""),
ctx: Invalid,
},
),
debug_text: None,
conversion: None,
format_spec: None,
},
),
],
flags: TStringFlags {
quote_style: Double,
prefix: Regular,
triple_quoted: false,
},
TString {
range: 44..48,
node_index: AtomicNodeIndex(..),
elements: [
Interpolation(
InterpolatedElement {
range: 46..47,
node_index: AtomicNodeIndex(..),
expression: Name(
ExprName {
node_index: AtomicNodeIndex(..),
range: 47..47,
id: Name(""),
ctx: Invalid,
},
),
debug_text: None,
conversion: None,
format_spec: None,
},
),
],
flags: TStringFlags {
quote_style: Double,
prefix: Regular,
triple_quoted: false,
},
),
},
),
},
},
@ -66,36 +64,34 @@ Module(
range: 49..58,
value: TStringValue {
inner: Single(
TString(
TString {
range: 49..58,
node_index: AtomicNodeIndex(..),
elements: [
Interpolation(
InterpolatedElement {
range: 51..58,
node_index: AtomicNodeIndex(..),
expression: Name(
ExprName {
node_index: AtomicNodeIndex(..),
range: 52..55,
id: Name("foo"),
ctx: Load,
},
),
debug_text: None,
conversion: None,
format_spec: None,
},
),
],
flags: TStringFlags {
quote_style: Double,
prefix: Regular,
triple_quoted: false,
},
TString {
range: 49..58,
node_index: AtomicNodeIndex(..),
elements: [
Interpolation(
InterpolatedElement {
range: 51..58,
node_index: AtomicNodeIndex(..),
expression: Name(
ExprName {
node_index: AtomicNodeIndex(..),
range: 52..55,
id: Name("foo"),
ctx: Load,
},
),
debug_text: None,
conversion: None,
format_spec: None,
},
),
],
flags: TStringFlags {
quote_style: Double,
prefix: Regular,
triple_quoted: false,
},
),
},
),
},
},
@ -112,41 +108,39 @@ Module(
range: 59..67,
value: TStringValue {
inner: Single(
TString(
TString {
range: 59..67,
node_index: AtomicNodeIndex(..),
elements: [
Interpolation(
InterpolatedElement {
range: 61..66,
node_index: AtomicNodeIndex(..),
expression: Name(
ExprName {
node_index: AtomicNodeIndex(..),
range: 62..65,
id: Name("foo"),
ctx: Load,
},
),
debug_text: Some(
DebugText {
leading: "",
trailing: "=",
},
),
conversion: None,
format_spec: None,
},
),
],
flags: TStringFlags {
quote_style: Double,
prefix: Regular,
triple_quoted: false,
},
TString {
range: 59..67,
node_index: AtomicNodeIndex(..),
elements: [
Interpolation(
InterpolatedElement {
range: 61..66,
node_index: AtomicNodeIndex(..),
expression: Name(
ExprName {
node_index: AtomicNodeIndex(..),
range: 62..65,
id: Name("foo"),
ctx: Load,
},
),
debug_text: Some(
DebugText {
leading: "",
trailing: "=",
},
),
conversion: None,
format_spec: None,
},
),
],
flags: TStringFlags {
quote_style: Double,
prefix: Regular,
triple_quoted: false,
},
),
},
),
},
},
@ -164,66 +158,62 @@ Module(
value: TStringValue {
inner: Concatenated(
[
TString(
TString {
range: 68..72,
node_index: AtomicNodeIndex(..),
elements: [
Interpolation(
InterpolatedElement {
range: 70..71,
node_index: AtomicNodeIndex(..),
expression: Name(
ExprName {
node_index: AtomicNodeIndex(..),
range: 71..71,
id: Name(""),
ctx: Invalid,
},
),
debug_text: None,
conversion: None,
format_spec: None,
},
),
],
flags: TStringFlags {
quote_style: Double,
prefix: Regular,
triple_quoted: false,
},
TString {
range: 68..72,
node_index: AtomicNodeIndex(..),
elements: [
Interpolation(
InterpolatedElement {
range: 70..71,
node_index: AtomicNodeIndex(..),
expression: Name(
ExprName {
node_index: AtomicNodeIndex(..),
range: 71..71,
id: Name(""),
ctx: Invalid,
},
),
debug_text: None,
conversion: None,
format_spec: None,
},
),
],
flags: TStringFlags {
quote_style: Double,
prefix: Regular,
triple_quoted: false,
},
),
TString(
TString {
range: 73..81,
node_index: AtomicNodeIndex(..),
elements: [
Interpolation(
InterpolatedElement {
range: 77..78,
node_index: AtomicNodeIndex(..),
expression: Name(
ExprName {
node_index: AtomicNodeIndex(..),
range: 78..78,
id: Name(""),
ctx: Invalid,
},
),
debug_text: None,
conversion: None,
format_spec: None,
},
),
],
flags: TStringFlags {
quote_style: Double,
prefix: Regular,
triple_quoted: true,
},
},
TString {
range: 73..81,
node_index: AtomicNodeIndex(..),
elements: [
Interpolation(
InterpolatedElement {
range: 77..78,
node_index: AtomicNodeIndex(..),
expression: Name(
ExprName {
node_index: AtomicNodeIndex(..),
range: 78..78,
id: Name(""),
ctx: Invalid,
},
),
debug_text: None,
conversion: None,
format_spec: None,
},
),
],
flags: TStringFlags {
quote_style: Double,
prefix: Regular,
triple_quoted: true,
},
),
},
],
),
},

View file

@ -20,49 +20,47 @@ Module(
range: 44..56,
value: TStringValue {
inner: Single(
TString(
TString {
range: 44..56,
node_index: AtomicNodeIndex(..),
elements: [
Literal(
InterpolatedStringLiteralElement {
range: 46..52,
node_index: AtomicNodeIndex(..),
value: "hello ",
},
),
Interpolation(
InterpolatedElement {
range: 52..55,
node_index: AtomicNodeIndex(..),
expression: Name(
ExprName {
node_index: AtomicNodeIndex(..),
range: 53..54,
id: Name("x"),
ctx: Load,
},
),
debug_text: None,
conversion: None,
format_spec: Some(
InterpolatedStringFormatSpec {
range: 55..55,
node_index: AtomicNodeIndex(..),
elements: [],
},
),
},
),
],
flags: TStringFlags {
quote_style: Double,
prefix: Regular,
triple_quoted: false,
},
TString {
range: 44..56,
node_index: AtomicNodeIndex(..),
elements: [
Literal(
InterpolatedStringLiteralElement {
range: 46..52,
node_index: AtomicNodeIndex(..),
value: "hello ",
},
),
Interpolation(
InterpolatedElement {
range: 52..55,
node_index: AtomicNodeIndex(..),
expression: Name(
ExprName {
node_index: AtomicNodeIndex(..),
range: 53..54,
id: Name("x"),
ctx: Load,
},
),
debug_text: None,
conversion: None,
format_spec: Some(
InterpolatedStringFormatSpec {
range: 55..55,
node_index: AtomicNodeIndex(..),
elements: [],
},
),
},
),
],
flags: TStringFlags {
quote_style: Double,
prefix: Regular,
triple_quoted: false,
},
),
},
),
},
},
@ -79,57 +77,55 @@ Module(
range: 57..72,
value: TStringValue {
inner: Single(
TString(
TString {
range: 57..72,
node_index: AtomicNodeIndex(..),
elements: [
Literal(
InterpolatedStringLiteralElement {
range: 59..65,
node_index: AtomicNodeIndex(..),
value: "hello ",
},
),
Interpolation(
InterpolatedElement {
range: 65..71,
node_index: AtomicNodeIndex(..),
expression: Name(
ExprName {
node_index: AtomicNodeIndex(..),
range: 66..67,
id: Name("x"),
ctx: Load,
},
),
debug_text: None,
conversion: None,
format_spec: Some(
InterpolatedStringFormatSpec {
range: 68..71,
node_index: AtomicNodeIndex(..),
elements: [
Literal(
InterpolatedStringLiteralElement {
range: 68..71,
node_index: AtomicNodeIndex(..),
value: ".3f",
},
),
],
},
),
},
),
],
flags: TStringFlags {
quote_style: Double,
prefix: Regular,
triple_quoted: false,
},
TString {
range: 57..72,
node_index: AtomicNodeIndex(..),
elements: [
Literal(
InterpolatedStringLiteralElement {
range: 59..65,
node_index: AtomicNodeIndex(..),
value: "hello ",
},
),
Interpolation(
InterpolatedElement {
range: 65..71,
node_index: AtomicNodeIndex(..),
expression: Name(
ExprName {
node_index: AtomicNodeIndex(..),
range: 66..67,
id: Name("x"),
ctx: Load,
},
),
debug_text: None,
conversion: None,
format_spec: Some(
InterpolatedStringFormatSpec {
range: 68..71,
node_index: AtomicNodeIndex(..),
elements: [
Literal(
InterpolatedStringLiteralElement {
range: 68..71,
node_index: AtomicNodeIndex(..),
value: ".3f",
},
),
],
},
),
},
),
],
flags: TStringFlags {
quote_style: Double,
prefix: Regular,
triple_quoted: false,
},
),
},
),
},
},

View file

@ -8,7 +8,7 @@ input_file: crates/ruff_python_parser/resources/inline/err/template_strings_py31
Module(
ModModule {
node_index: AtomicNodeIndex(..),
range: 0..117,
range: 0..89,
body: [
Expr(
StmtExpr {
@ -20,36 +20,34 @@ Module(
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,
},
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,
},
),
},
),
},
},
@ -66,36 +64,34 @@ Module(
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,
},
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,
},
),
},
),
},
},
@ -112,76 +108,24 @@ Module(
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,
},
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,
},
},
),
],
},
),
},
},
@ -219,13 +163,4 @@ Module(
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)
|

View file

@ -8,7 +8,7 @@ input_file: crates/ruff_python_parser/resources/inline/ok/template_strings_py314
Module(
ModModule {
node_index: AtomicNodeIndex(..),
range: 0..117,
range: 0..89,
body: [
Expr(
StmtExpr {
@ -20,36 +20,34 @@ Module(
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,
},
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,
},
),
},
),
},
},
@ -66,36 +64,34 @@ Module(
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,
},
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,
},
),
},
),
},
},
@ -112,76 +108,24 @@ Module(
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,
},
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,
},
},
),
],
},
),
},
},