Skip to content

Commit f1c7aeb

Browse files
authored
Merge pull request #4115 from youknowone/fstring
Fix f-string self-documenting format
2 parents 138c699 + 43d2b97 commit f1c7aeb

7 files changed

+21
-13
lines changed

bytecode/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@ impl fmt::Display for Label {
162162
#[repr(u8)]
163163
pub enum ConversionFlag {
164164
/// No conversion
165-
None = 0,
165+
None = 0, // CPython uses -1 but not pleasure for us
166166
/// Converts by calling `str(<value>)`.
167167
Str = b's',
168168
/// Converts by calling `ascii(<value>)`.

extra_tests/snippets/syntax_fstring.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@
3838

3939

4040
# base test of self documenting strings
41-
#assert f'{foo=}' == 'foo=bar' # TODO ' missing
41+
assert f'{foo=}' == "foo='bar'" # TODO ' missing
4242

4343
num=42
4444

parser/src/fstring.rs

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ impl<'a> FStringParser<'a> {
3131
let mut spec = None;
3232
let mut delims = Vec::new();
3333
let mut conversion = ConversionFlag::None;
34-
let mut pred_expression_text = String::new();
34+
let mut self_documenting = false;
3535
let mut trailing_seq = String::new();
3636

3737
while let Some(ch) = self.chars.next() {
@@ -87,7 +87,7 @@ impl<'a> FStringParser<'a> {
8787
// match a python 3.8 self documenting expression
8888
// format '{' PYTHON_EXPRESSION '=' FORMAT_SPECIFIER? '}'
8989
'=' if self.chars.peek() != Some(&'=') && delims.is_empty() => {
90-
pred_expression_text = expression.to_string(); // safe expression before = to print it
90+
self_documenting = true;
9191
}
9292

9393
':' if delims.is_empty() => {
@@ -182,7 +182,7 @@ impl<'a> FStringParser<'a> {
182182
if expression.is_empty() {
183183
return Err(EmptyExpression);
184184
}
185-
let ret = if pred_expression_text.is_empty() {
185+
let ret = if !self_documenting {
186186
vec![self.expr(ExprKind::FormattedValue {
187187
value: Box::new(
188188
parse_fstring_expr(&expression)
@@ -194,7 +194,7 @@ impl<'a> FStringParser<'a> {
194194
} else {
195195
vec![
196196
self.expr(ExprKind::Constant {
197-
value: Constant::Str(pred_expression_text + "="),
197+
value: Constant::Str(expression.clone() + "="),
198198
kind: None,
199199
}),
200200
self.expr(ExprKind::Constant {
@@ -206,7 +206,12 @@ impl<'a> FStringParser<'a> {
206206
parse_fstring_expr(&expression)
207207
.map_err(|e| InvalidExpression(Box::new(e.error)))?,
208208
),
209-
conversion: conversion as _,
209+
conversion: (if conversion == ConversionFlag::None && spec.is_none()
210+
{
211+
ConversionFlag::Repr
212+
} else {
213+
conversion
214+
}) as _,
210215
format_spec: spec,
211216
}),
212217
]
@@ -222,10 +227,13 @@ impl<'a> FStringParser<'a> {
222227
}
223228
}
224229
}
225-
' ' if !pred_expression_text.is_empty() => {
230+
' ' if self_documenting => {
226231
trailing_seq.push(ch);
227232
}
228233
_ => {
234+
if self_documenting {
235+
return Err(ExpectedRbrace);
236+
}
229237
expression.push(ch);
230238
}
231239
}

parser/src/snapshots/rustpython_parser__fstring__tests__fstring_parse_selfdocumenting_base.snap

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ Located {
5454
ctx: Load,
5555
},
5656
},
57-
conversion: 0,
57+
conversion: 114,
5858
format_spec: None,
5959
},
6060
},

parser/src/snapshots/rustpython_parser__fstring__tests__fstring_parse_selfdocumenting_base_more.snap

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ Located {
6767
ctx: Load,
6868
},
6969
},
70-
conversion: 0,
70+
conversion: 114,
7171
format_spec: None,
7272
},
7373
},
@@ -128,7 +128,7 @@ Located {
128128
ctx: Load,
129129
},
130130
},
131-
conversion: 0,
131+
conversion: 114,
132132
format_spec: None,
133133
},
134134
},

parser/src/snapshots/rustpython_parser__fstring__tests__parse_fstring_selfdoc_prec_space.snap

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ Located {
5454
ctx: Load,
5555
},
5656
},
57-
conversion: 0,
57+
conversion: 114,
5858
format_spec: None,
5959
},
6060
},

parser/src/snapshots/rustpython_parser__fstring__tests__parse_fstring_selfdoc_trailing_space.snap

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ Located {
5454
ctx: Load,
5555
},
5656
},
57-
conversion: 0,
57+
conversion: 114,
5858
format_spec: None,
5959
},
6060
},

0 commit comments

Comments
 (0)