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