@@ -909,8 +909,6 @@ _PyPegen_check_fstring_conversion(Parser *p, Token *conv_token, expr_ty conv) {
909
909
return result_token_with_metadata (p , conv , conv_token -> metadata );
910
910
}
911
911
912
- static asdl_expr_seq *
913
- unpack_top_level_joined_strs (Parser * p , asdl_expr_seq * raw_expressions );
914
912
ResultTokenWithMetadata *
915
913
_PyPegen_setup_full_format_spec (Parser * p , Token * colon , asdl_expr_seq * spec ,
916
914
int lineno , int col_offset , int end_lineno ,
@@ -1192,68 +1190,62 @@ static expr_ty _PyPegen_decode_fstring_part(Parser *p, int is_raw,
1192
1190
p -> arena );
1193
1191
}
1194
1192
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
+
1197
1196
/* The parser might put multiple f-string values into an individual
1198
1197
* JoinedStr node at the top level due to stuff like f-string debugging
1199
1198
* expressions. This function flattens those and promotes them to the
1200
1199
* upper level. Only simplifies AST, but the compiler already takes care
1201
1200
* of the regular output, so this is not necessary if you are not going
1202
1201
* to expose the output AST to Python level. */
1203
1202
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 ;
1228
1209
}
1229
- } else {
1230
- asdl_seq_SET (expressions , req_index , expr );
1231
- req_index ++ ;
1232
- }
1233
1210
}
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 );
1242
1211
1243
1212
const char * quote_str = PyBytes_AsString (a -> bytes );
1244
1213
if (quote_str == NULL ) {
1245
1214
return NULL ;
1246
1215
}
1247
1216
int is_raw = strpbrk (quote_str , "rR" ) != NULL ;
1248
1217
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 );
1250
1219
if (seq == NULL ) {
1251
1220
return NULL ;
1252
1221
}
1253
1222
1254
1223
Py_ssize_t index = 0 ;
1255
1224
for (Py_ssize_t i = 0 ; i < n_items ; i ++ ) {
1256
1225
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
+ }
1257
1249
if (item -> kind == Constant_kind ) {
1258
1250
item = _PyPegen_decode_fstring_part (p , is_raw , item , b );
1259
1251
if (item == NULL ) {
@@ -1272,7 +1264,7 @@ expr_ty _PyPegen_joined_str(Parser *p, Token *a, asdl_expr_seq *raw_expressions,
1272
1264
}
1273
1265
1274
1266
asdl_expr_seq * resized_exprs ;
1275
- if (index != n_items ) {
1267
+ if (index != total_items ) {
1276
1268
resized_exprs = _Py_asdl_expr_seq_new (index , p -> arena );
1277
1269
if (resized_exprs == NULL ) {
1278
1270
return NULL ;
0 commit comments