@@ -1305,19 +1305,42 @@ _PyPegen_joined_str(Parser *p, Token* a, asdl_expr_seq* raw_expressions, Token*b
1305
1305
if (seq == NULL ) {
1306
1306
return NULL ;
1307
1307
}
1308
- Py_ssize_t i = 0 ;
1309
- for (i = 0 ; i < asdl_seq_LEN (expr ); i ++ ) {
1308
+
1309
+ Py_ssize_t index = 0 ;
1310
+ for (Py_ssize_t i = 0 ; i < n_items ; i ++ ) {
1310
1311
expr_ty item = asdl_seq_GET (expr , i );
1311
1312
if (item -> kind == Constant_kind ) {
1312
1313
item = _PyPegen_decode_fstring_part (p , is_raw , item );
1313
1314
if (item == NULL ) {
1314
1315
return NULL ;
1315
1316
}
1317
+
1318
+ /* Tokenizer emits string parts even when the underlying string
1319
+ might become an empty value (e.g. FSTRING_MIDDLE with the value \\n)
1320
+ so we need to check for them and simplify it here. */
1321
+ if (PyUnicode_CheckExact (item -> v .Constant .value )
1322
+ && PyUnicode_GET_LENGTH (item -> v .Constant .value ) == 0 ) {
1323
+ continue ;
1324
+ }
1316
1325
}
1317
- asdl_seq_SET (seq , i , item );
1326
+ asdl_seq_SET (seq , index ++ , item );
1327
+ }
1328
+
1329
+ asdl_expr_seq * resized_exprs ;
1330
+ if (index != n_items ) {
1331
+ resized_exprs = _Py_asdl_expr_seq_new (index , p -> arena );
1332
+ if (resized_exprs == NULL ) {
1333
+ return NULL ;
1334
+ }
1335
+ for (Py_ssize_t i = 0 ; i < index ; i ++ ) {
1336
+ asdl_seq_SET (resized_exprs , i , asdl_seq_GET (seq , i ));
1337
+ }
1338
+ }
1339
+ else {
1340
+ resized_exprs = seq ;
1318
1341
}
1319
1342
1320
- return _PyAST_JoinedStr (seq , a -> lineno , a -> col_offset ,
1343
+ return _PyAST_JoinedStr (resized_exprs , a -> lineno , a -> col_offset ,
1321
1344
b -> end_lineno , b -> end_col_offset ,
1322
1345
p -> arena );
1323
1346
}
0 commit comments