@@ -5006,10 +5006,16 @@ fstring_parse(const char **str, const char *end, int raw, int recurse_lvl,
50065006 closing brace doesn't match an opening paren, for example. It
50075007 doesn't need to error on all invalid expressions, just correctly
50085008 find the end of all valid ones. Any errors inside the expression
5009- will be caught when we parse it later. */
5009+ will be caught when we parse it later.
5010+
5011+ *expression is set to the expression. For an '=' "debug" expression,
5012+ *expr_text is set to the debug text (the original text of the expression,
5013+ *including the '=' and any whitespace around it, as a string object). If
5014+ *not a debug expression, *expr_text set to NULL. */
50105015static int
50115016fstring_find_expr (const char * * str , const char * end , int raw , int recurse_lvl ,
5012- expr_ty * expression , struct compiling * c , const node * n )
5017+ PyObject * * expr_text , expr_ty * expression ,
5018+ struct compiling * c , const node * n )
50135019{
50145020 /* Return -1 on error, else 0. */
50155021
@@ -5020,9 +5026,6 @@ fstring_find_expr(const char **str, const char *end, int raw, int recurse_lvl,
50205026 int conversion = -1 ; /* The conversion char. Use default if not
50215027 specified, or !r if using = and no format
50225028 spec. */
5023- int equal_flag = 0 ; /* Are we using the = feature? */
5024- PyObject * expr_text = NULL ; /* The text of the expression, used for =. */
5025- const char * expr_text_end ;
50265029
50275030 /* 0 if we're not in a string, else the quote char we're trying to
50285031 match (single or double quote). */
@@ -5198,15 +5201,21 @@ fstring_find_expr(const char **str, const char *end, int raw, int recurse_lvl,
51985201 expr_text. */
51995202 if (* * str == '=' ) {
52005203 * str += 1 ;
5201- equal_flag = 1 ;
52025204
52035205 /* Skip over ASCII whitespace. No need to test for end of string
52045206 here, since we know there's at least a trailing quote somewhere
52055207 ahead. */
52065208 while (Py_ISSPACE (* * str )) {
52075209 * str += 1 ;
52085210 }
5209- expr_text_end = * str ;
5211+
5212+ /* Set *expr_text to the text of the expression. */
5213+ * expr_text = PyUnicode_FromStringAndSize (expr_start , * str - expr_start );
5214+ if (!* expr_text ) {
5215+ goto error ;
5216+ }
5217+ } else {
5218+ * expr_text = NULL ;
52105219 }
52115220
52125221 /* Check for a conversion char, if present. */
@@ -5227,17 +5236,6 @@ fstring_find_expr(const char **str, const char *end, int raw, int recurse_lvl,
52275236 }
52285237
52295238 }
5230- if (equal_flag ) {
5231- Py_ssize_t len = expr_text_end - expr_start ;
5232- expr_text = PyUnicode_FromStringAndSize (expr_start , len );
5233- if (!expr_text ) {
5234- goto error ;
5235- }
5236- if (PyArena_AddPyObject (c -> c_arena , expr_text ) < 0 ) {
5237- Py_DECREF (expr_text );
5238- goto error ;
5239- }
5240- }
52415239
52425240 /* Check for the format spec, if present. */
52435241 if (* str >= end )
@@ -5261,16 +5259,16 @@ fstring_find_expr(const char **str, const char *end, int raw, int recurse_lvl,
52615259 assert (* * str == '}' );
52625260 * str += 1 ;
52635261
5264- /* If we're in = mode, and have no format spec and no explict conversion,
5265- set the conversion to 'r'. */
5266- if (equal_flag && format_spec == NULL && conversion == -1 ) {
5262+ /* If we're in = mode (detected by non-NULL expr_text), and have no format
5263+ spec and no explict conversion, set the conversion to 'r'. */
5264+ if (* expr_text && format_spec == NULL && conversion == -1 ) {
52675265 conversion = 'r' ;
52685266 }
52695267
52705268 /* And now create the FormattedValue node that represents this
52715269 entire expression with the conversion and format spec. */
52725270 * expression = FormattedValue (simple_expression , conversion ,
5273- format_spec , expr_text , LINENO (n ),
5271+ format_spec , LINENO (n ),
52745272 n -> n_col_offset , n -> n_end_lineno ,
52755273 n -> n_end_col_offset , c -> c_arena );
52765274 if (!* expression )
@@ -5313,7 +5311,7 @@ fstring_find_expr(const char **str, const char *end, int raw, int recurse_lvl,
53135311static int
53145312fstring_find_literal_and_expr (const char * * str , const char * end , int raw ,
53155313 int recurse_lvl , PyObject * * literal ,
5316- expr_ty * expression ,
5314+ PyObject * * expr_text , expr_ty * expression ,
53175315 struct compiling * c , const node * n )
53185316{
53195317 int result ;
@@ -5341,7 +5339,8 @@ fstring_find_literal_and_expr(const char **str, const char *end, int raw,
53415339 /* We must now be the start of an expression, on a '{'. */
53425340 assert (* * str == '{' );
53435341
5344- if (fstring_find_expr (str , end , raw , recurse_lvl , expression , c , n ) < 0 )
5342+ if (fstring_find_expr (str , end , raw , recurse_lvl , expr_text ,
5343+ expression , c , n ) < 0 )
53455344 goto error ;
53465345
53475346 return 0 ;
@@ -5604,39 +5603,42 @@ FstringParser_ConcatFstring(FstringParser *state, const char **str,
56045603
56055604 /* Parse the f-string. */
56065605 while (1 ) {
5607- PyObject * literal = NULL ;
5606+ PyObject * literal [ 2 ] = { NULL , NULL } ;
56085607 expr_ty expression = NULL ;
56095608
56105609 /* If there's a zero length literal in front of the
56115610 expression, literal will be NULL. If we're at the end of
56125611 the f-string, expression will be NULL (unless result == 1,
56135612 see below). */
56145613 int result = fstring_find_literal_and_expr (str , end , raw , recurse_lvl ,
5615- & literal , & expression ,
5616- c , n );
5614+ & literal [ 0 ] , & literal [ 1 ] ,
5615+ & expression , c , n );
56175616 if (result < 0 )
56185617 return -1 ;
56195618
5620- /* Add the literal, if any. */
5621- if (!literal ) {
5622- /* Do nothing. Just leave last_str alone (and possibly
5623- NULL). */
5624- } else if (!state -> last_str ) {
5625- /* Note that the literal can be zero length, if the
5626- input string is "\\\n" or "\\\r", among others. */
5627- state -> last_str = literal ;
5628- literal = NULL ;
5629- } else {
5630- /* We have a literal, concatenate it. */
5631- assert (PyUnicode_GET_LENGTH (literal ) != 0 );
5632- if (FstringParser_ConcatAndDel (state , literal ) < 0 )
5633- return -1 ;
5634- literal = NULL ;
5619+ /* Add the literals, if any. */
5620+ for (int i = 0 ; i < 2 ; i ++ ) {
5621+ if (!literal [i ]) {
5622+ /* Do nothing. Just leave last_str alone (and possibly
5623+ NULL). */
5624+ } else if (!state -> last_str ) {
5625+ /* Note that the literal can be zero length, if the
5626+ input string is "\\\n" or "\\\r", among others. */
5627+ state -> last_str = literal [i ];
5628+ literal [i ] = NULL ;
5629+ } else {
5630+ /* We have a literal, concatenate it. */
5631+ assert (PyUnicode_GET_LENGTH (literal [i ]) != 0 );
5632+ if (FstringParser_ConcatAndDel (state , literal [i ]) < 0 )
5633+ return -1 ;
5634+ literal [i ] = NULL ;
5635+ }
56355636 }
56365637
5637- /* We've dealt with the literal now. It can't be leaked on further
5638+ /* We've dealt with the literals now. They can't be leaked on further
56385639 errors. */
5639- assert (literal == NULL );
5640+ assert (literal [0 ] == NULL );
5641+ assert (literal [1 ] == NULL );
56405642
56415643 /* See if we should just loop around to get the next literal
56425644 and expression, while ignoring the expression this
0 commit comments