@@ -969,8 +969,6 @@ _PyPegen_check_fstring_conversion(Parser *p, Token* conv_token, expr_ty conv)
969
969
return result_token_with_metadata (p , conv , conv_token -> metadata );
970
970
}
971
971
972
- static asdl_expr_seq *
973
- unpack_top_level_joined_strs (Parser * p , asdl_expr_seq * raw_expressions );
974
972
ResultTokenWithMetadata *
975
973
_PyPegen_setup_full_format_spec (Parser * p , Token * colon , asdl_expr_seq * spec , int lineno , int col_offset ,
976
974
int end_lineno , int end_col_offset , PyArena * arena )
@@ -1279,69 +1277,64 @@ _PyPegen_decode_fstring_part(Parser* p, int is_raw, expr_ty constant, Token* tok
1279
1277
p -> arena );
1280
1278
}
1281
1279
1282
- static asdl_expr_seq *
1283
- unpack_top_level_joined_strs (Parser * p , asdl_expr_seq * raw_expressions )
1284
- {
1280
+ expr_ty
1281
+ _PyPegen_joined_str (Parser * p , Token * a , asdl_expr_seq * expr , Token * b ) {
1282
+
1285
1283
/* The parser might put multiple f-string values into an individual
1286
1284
* JoinedStr node at the top level due to stuff like f-string debugging
1287
1285
* expressions. This function flattens those and promotes them to the
1288
1286
* upper level. Only simplifies AST, but the compiler already takes care
1289
1287
* of the regular output, so this is not necessary if you are not going
1290
1288
* to expose the output AST to Python level. */
1291
1289
1292
- Py_ssize_t i , req_size , raw_size ;
1293
-
1294
- req_size = raw_size = asdl_seq_LEN (raw_expressions );
1295
- expr_ty expr ;
1296
- for (i = 0 ; i < raw_size ; i ++ ) {
1297
- expr = asdl_seq_GET (raw_expressions , i );
1298
- if (expr -> kind == JoinedStr_kind ) {
1299
- req_size += asdl_seq_LEN (expr -> v .JoinedStr .values ) - 1 ;
1300
- }
1301
- }
1302
-
1303
- asdl_expr_seq * expressions = _Py_asdl_expr_seq_new (req_size , p -> arena );
1304
- if (expressions == NULL ) {
1305
- return NULL ;
1306
- }
1307
-
1308
- Py_ssize_t raw_index , req_index = 0 ;
1309
- for (raw_index = 0 ; raw_index < raw_size ; raw_index ++ ) {
1310
- expr = asdl_seq_GET (raw_expressions , raw_index );
1311
- if (expr -> kind == JoinedStr_kind ) {
1312
- asdl_expr_seq * values = expr -> v .JoinedStr .values ;
1313
- for (Py_ssize_t n = 0 ; n < asdl_seq_LEN (values ); n ++ ) {
1314
- asdl_seq_SET (expressions , req_index , asdl_seq_GET (values , n ));
1315
- req_index ++ ;
1316
- }
1317
- } else {
1318
- asdl_seq_SET (expressions , req_index , expr );
1319
- req_index ++ ;
1290
+ Py_ssize_t n_items = asdl_seq_LEN (expr );
1291
+ Py_ssize_t total_items = n_items ;
1292
+ for (Py_ssize_t i = 0 ; i < n_items ; i ++ ) {
1293
+ expr_ty item = asdl_seq_GET (expr , i );
1294
+ if (item -> kind == JoinedStr_kind ) {
1295
+ total_items += asdl_seq_LEN (item -> v .JoinedStr .values ) - 1 ;
1320
1296
}
1321
1297
}
1322
- return expressions ;
1323
- }
1324
-
1325
- expr_ty
1326
- _PyPegen_joined_str (Parser * p , Token * a , asdl_expr_seq * raw_expressions , Token * b ) {
1327
-
1328
- asdl_expr_seq * expr = unpack_top_level_joined_strs (p , raw_expressions );
1329
- Py_ssize_t n_items = asdl_seq_LEN (expr );
1330
1298
1331
1299
const char * quote_str = PyBytes_AsString (a -> bytes );
1332
1300
if (quote_str == NULL ) {
1333
1301
return NULL ;
1334
1302
}
1335
1303
int is_raw = strpbrk (quote_str , "rR" ) != NULL ;
1336
1304
1337
- asdl_expr_seq * seq = _Py_asdl_expr_seq_new (n_items , p -> arena );
1305
+ asdl_expr_seq * seq = _Py_asdl_expr_seq_new (total_items , p -> arena );
1338
1306
if (seq == NULL ) {
1339
1307
return NULL ;
1340
1308
}
1341
1309
1342
1310
Py_ssize_t index = 0 ;
1343
1311
for (Py_ssize_t i = 0 ; i < n_items ; i ++ ) {
1344
1312
expr_ty item = asdl_seq_GET (expr , i );
1313
+
1314
+ // This should correspond to a JoinedStr node of two elements
1315
+ // created _PyPegen_formatted_value. This situation can only be the result of
1316
+ // a f-string debug expression where the first element is a constant with the text and the second
1317
+ // a formatted value with the expression.
1318
+ if (item -> kind == JoinedStr_kind ) {
1319
+ asdl_expr_seq * values = item -> v .JoinedStr .values ;
1320
+ if (asdl_seq_LEN (values ) != 2 ) {
1321
+ PyErr_Format (PyExc_SystemError ,
1322
+ "unexpected JoinedStr node without debug data in f-string at line %d" ,
1323
+ item -> lineno );
1324
+ return NULL ;
1325
+ }
1326
+
1327
+ expr_ty first = asdl_seq_GET (values , 0 );
1328
+ assert (first -> kind == Constant_kind );
1329
+ asdl_seq_SET (seq , index ++ , first );
1330
+
1331
+ expr_ty second = asdl_seq_GET (values , 1 );
1332
+ assert (second -> kind == FormattedValue_kind );
1333
+ asdl_seq_SET (seq , index ++ , second );
1334
+
1335
+ continue ;
1336
+ }
1337
+
1345
1338
if (item -> kind == Constant_kind ) {
1346
1339
item = _PyPegen_decode_fstring_part (p , is_raw , item , b );
1347
1340
if (item == NULL ) {
@@ -1360,7 +1353,7 @@ _PyPegen_joined_str(Parser *p, Token* a, asdl_expr_seq* raw_expressions, Token*b
1360
1353
}
1361
1354
1362
1355
asdl_expr_seq * resized_exprs ;
1363
- if (index != n_items ) {
1356
+ if (index != total_items ) {
1364
1357
resized_exprs = _Py_asdl_expr_seq_new (index , p -> arena );
1365
1358
if (resized_exprs == NULL ) {
1366
1359
return NULL ;
0 commit comments