@@ -909,8 +909,6 @@ _PyPegen_check_fstring_conversion(Parser *p, Token *conv_token, expr_ty conv) {
909909  return  result_token_with_metadata (p , conv , conv_token -> metadata );
910910}
911911
912- static  asdl_expr_seq  * 
913- unpack_top_level_joined_strs (Parser  * p , asdl_expr_seq  * raw_expressions );
914912ResultTokenWithMetadata  * 
915913_PyPegen_setup_full_format_spec (Parser  * p , Token  * colon , asdl_expr_seq  * spec ,
916914                                int  lineno , int  col_offset , int  end_lineno ,
@@ -1192,68 +1190,62 @@ static expr_ty _PyPegen_decode_fstring_part(Parser *p, int is_raw,
11921190                         p -> arena );
11931191}
11941192
1195- static  asdl_expr_seq  * 
1196- unpack_top_level_joined_strs (Parser  * p , asdl_expr_seq  * raw_expressions ) {
1193+ expr_ty 
1194+ _PyPegen_joined_str (Parser  * p , Token *  a , asdl_expr_seq *  expr , Token * b ) {
1195+ 
11971196  /* The parser might put multiple f-string values into an individual 
11981197   * JoinedStr node at the top level due to stuff like f-string debugging 
11991198   * expressions. This function flattens those and promotes them to the 
12001199   * upper level. Only simplifies AST, but the compiler already takes care 
12011200   * of the regular output, so this is not necessary if you are not going 
12021201   * to expose the output AST to Python level. */ 
12031202
1204-   Py_ssize_t  i , req_size , raw_size ;
1205- 
1206-   req_size  =  raw_size  =  asdl_seq_LEN (raw_expressions );
1207-   expr_ty  expr ;
1208-   for  (i  =  0 ; i  <  raw_size ; i ++ ) {
1209-     expr  =  asdl_seq_GET (raw_expressions , i );
1210-     if  (expr -> kind  ==  JoinedStr_kind ) {
1211-       req_size  +=  asdl_seq_LEN (expr -> v .JoinedStr .values ) -  1 ;
1212-     }
1213-   }
1214- 
1215-   asdl_expr_seq  * expressions  =  _Py_asdl_expr_seq_new (req_size , p -> arena );
1216-   if  (expressions  ==  NULL ) {
1217-     return  NULL ;
1218-   }
1219- 
1220-   Py_ssize_t  raw_index , req_index  =  0 ;
1221-   for  (raw_index  =  0 ; raw_index  <  raw_size ; raw_index ++ ) {
1222-     expr  =  asdl_seq_GET (raw_expressions , raw_index );
1223-     if  (expr -> kind  ==  JoinedStr_kind ) {
1224-       asdl_expr_seq  * values  =  expr -> v .JoinedStr .values ;
1225-       for  (Py_ssize_t  n  =  0 ; n  <  asdl_seq_LEN (values ); n ++ ) {
1226-         asdl_seq_SET (expressions , req_index , asdl_seq_GET (values , n ));
1227-         req_index ++ ;
1203+   Py_ssize_t  n_items  =  asdl_seq_LEN (expr );
1204+   Py_ssize_t  total_items  =  n_items ;
1205+   for  (Py_ssize_t  i  =  0 ; i  <  n_items ; i ++ ) {
1206+       expr_ty  item  =  asdl_seq_GET (expr , i );
1207+       if  (item -> kind  ==  JoinedStr_kind ) {
1208+           total_items  +=  asdl_seq_LEN (item -> v .JoinedStr .values ) -  1 ;
12281209      }
1229-     } else  {
1230-       asdl_seq_SET (expressions , req_index , expr );
1231-       req_index ++ ;
1232-     }
12331210  }
1234-   return  expressions ;
1235- }
1236- 
1237- expr_ty  _PyPegen_joined_str (Parser  * p , Token  * a , asdl_expr_seq  * raw_expressions ,
1238-                             Token  * b ) {
1239- 
1240-   asdl_expr_seq  * expr  =  unpack_top_level_joined_strs (p , raw_expressions );
1241-   Py_ssize_t  n_items  =  asdl_seq_LEN (expr );
12421211
12431212  const  char  * quote_str  =  PyBytes_AsString (a -> bytes );
12441213  if  (quote_str  ==  NULL ) {
12451214    return  NULL ;
12461215  }
12471216  int  is_raw  =  strpbrk (quote_str , "rR" ) !=  NULL ;
12481217
1249-   asdl_expr_seq  * seq  =  _Py_asdl_expr_seq_new (n_items , p -> arena );
1218+   asdl_expr_seq  * seq  =  _Py_asdl_expr_seq_new (total_items , p -> arena );
12501219  if  (seq  ==  NULL ) {
12511220    return  NULL ;
12521221  }
12531222
12541223  Py_ssize_t  index  =  0 ;
12551224  for  (Py_ssize_t  i  =  0 ; i  <  n_items ; i ++ ) {
12561225    expr_ty  item  =  asdl_seq_GET (expr , i );
1226+     // This should correspond to a JoinedStr node of two elements 
1227+     // created _PyPegen_formatted_value. This situation can only be the result of 
1228+     // a f-string debug expression where the first element is a constant with the text and the second 
1229+     // a formatted value with the expression. 
1230+     if  (item -> kind  ==  JoinedStr_kind ) {
1231+         asdl_expr_seq  * values  =  item -> v .JoinedStr .values ;
1232+         if  (asdl_seq_LEN (values ) !=  2 ) {
1233+             PyErr_Format (PyExc_SystemError ,
1234+                           "unexpected JoinedStr node without debug data in f-string at line %d" ,
1235+                           item -> lineno );
1236+             return  NULL ;
1237+         }
1238+ 
1239+         expr_ty  first  =  asdl_seq_GET (values , 0 );
1240+         assert (first -> kind  ==  Constant_kind );
1241+         asdl_seq_SET (seq , index ++ , first );
1242+ 
1243+         expr_ty  second  =  asdl_seq_GET (values , 1 );
1244+         assert (second -> kind  ==  FormattedValue_kind );
1245+         asdl_seq_SET (seq , index ++ , second );
1246+ 
1247+         continue ;
1248+     }
12571249    if  (item -> kind  ==  Constant_kind ) {
12581250      item  =  _PyPegen_decode_fstring_part (p , is_raw , item , b );
12591251      if  (item  ==  NULL ) {
@@ -1272,7 +1264,7 @@ expr_ty _PyPegen_joined_str(Parser *p, Token *a, asdl_expr_seq *raw_expressions,
12721264  }
12731265
12741266  asdl_expr_seq  * resized_exprs ;
1275-   if  (index  !=  n_items ) {
1267+   if  (index  !=  total_items ) {
12761268    resized_exprs  =  _Py_asdl_expr_seq_new (index , p -> arena );
12771269    if  (resized_exprs  ==  NULL ) {
12781270      return  NULL ;
0 commit comments