@@ -2350,7 +2350,7 @@ _PyPegen_concatenate_strings2(Parser *p, asdl_expr_seq *strings,
2350
2350
int bytes_found = 0 ;
2351
2351
2352
2352
Py_ssize_t i = 0 ;
2353
- Py_ssize_t n_elements = 0 ;
2353
+ Py_ssize_t n_flattened_elements = 0 ;
2354
2354
for (i = 0 ; i < len ; i ++ ) {
2355
2355
expr_ty elem = asdl_seq_GET (strings , i );
2356
2356
if (elem -> kind == Constant_kind ) {
@@ -2359,9 +2359,9 @@ _PyPegen_concatenate_strings2(Parser *p, asdl_expr_seq *strings,
2359
2359
} else {
2360
2360
unicode_string_found = 1 ;
2361
2361
}
2362
- n_elements ++ ;
2362
+ n_flattened_elements ++ ;
2363
2363
} else {
2364
- n_elements += asdl_seq_LEN (elem -> v .JoinedStr .values );
2364
+ n_flattened_elements += asdl_seq_LEN (elem -> v .JoinedStr .values );
2365
2365
f_string_found = 1 ;
2366
2366
}
2367
2367
}
@@ -2383,28 +2383,100 @@ _PyPegen_concatenate_strings2(Parser *p, asdl_expr_seq *strings,
2383
2383
return _PyAST_Constant (res , NULL , lineno , col_offset , end_lineno , end_col_offset , p -> arena );
2384
2384
}
2385
2385
2386
- asdl_expr_seq * values = _Py_asdl_expr_seq_new (n_elements , p -> arena );
2387
- if (values == NULL ) {
2386
+ if (!f_string_found && len == 1 ) {
2387
+ return asdl_seq_GET (strings , 0 );
2388
+ }
2389
+
2390
+ asdl_expr_seq * flattened = _Py_asdl_expr_seq_new (n_flattened_elements , p -> arena );
2391
+ if (flattened == NULL ) {
2388
2392
return NULL ;
2389
2393
}
2390
2394
2395
+ /* build flattened list */
2391
2396
Py_ssize_t current_pos = 0 ;
2392
2397
Py_ssize_t j = 0 ;
2393
2398
for (i = 0 ; i < len ; i ++ ) {
2394
2399
expr_ty elem = asdl_seq_GET (strings , i );
2395
2400
if (elem -> kind == Constant_kind ) {
2396
- asdl_seq_SET (values , current_pos ++ , elem );
2401
+ asdl_seq_SET (flattened , current_pos ++ , elem );
2397
2402
} else {
2398
2403
for (j = 0 ; j < asdl_seq_LEN (elem -> v .JoinedStr .values ); j ++ ) {
2399
2404
expr_ty subvalue = asdl_seq_GET (elem -> v .JoinedStr .values , j );
2400
2405
if (subvalue == NULL ) {
2401
2406
return NULL ;
2402
2407
}
2403
- asdl_seq_SET (values , current_pos ++ , subvalue );
2408
+ asdl_seq_SET (flattened , current_pos ++ , subvalue );
2409
+ }
2410
+ }
2411
+ }
2412
+
2413
+ /* calculate folded element count */
2414
+ Py_ssize_t n_elements = 0 ;
2415
+ int prev_is_constant = 0 ;
2416
+ for (i = 0 ; i < n_flattened_elements ; i ++ ) {
2417
+ expr_ty elem = asdl_seq_GET (flattened , i );
2418
+ if (!prev_is_constant || elem -> kind != Constant_kind ) {
2419
+ n_elements ++ ;
2420
+ }
2421
+ prev_is_constant = elem -> kind == Constant_kind ;
2422
+ }
2423
+
2424
+ asdl_expr_seq * values = _Py_asdl_expr_seq_new (n_elements , p -> arena );
2425
+ if (values == NULL ) {
2426
+ return NULL ;
2427
+ }
2428
+
2429
+ /* build folded list */
2430
+ _PyUnicodeWriter writer ;
2431
+ current_pos = 0 ;
2432
+ for (i = 0 ; i < n_flattened_elements ; i ++ ) {
2433
+ expr_ty elem = asdl_seq_GET (flattened , i );
2434
+
2435
+ /* if the current elem and the following are constants,
2436
+ fold them and all consequent constants */
2437
+ if (elem -> kind == Constant_kind && i + 1 < n_flattened_elements
2438
+ && asdl_seq_GET (flattened , i + 1 )-> kind == Constant_kind ) {
2439
+
2440
+ _PyUnicodeWriter_Init (& writer );
2441
+ expr_ty last_elem = elem ;
2442
+ for (j = i ; j < n_flattened_elements ; j ++ ) {
2443
+ elem = asdl_seq_GET (flattened , j );
2444
+ if (elem -> kind == Constant_kind ) {
2445
+ if (_PyUnicodeWriter_WriteStr (& writer , elem -> v .Constant .value )) {
2446
+ _PyUnicodeWriter_Dealloc (& writer );
2447
+ return NULL ;
2448
+ }
2449
+ last_elem = elem ;
2450
+ } else {
2451
+ break ;
2452
+ }
2453
+ }
2454
+ i = j - 1 ;
2455
+
2456
+ PyObject * concat_str = _PyUnicodeWriter_Finish (& writer );
2457
+ if (concat_str == NULL ) {
2458
+ _PyUnicodeWriter_Dealloc (& writer );
2459
+ return NULL ;
2460
+ }
2461
+
2462
+ elem = _PyAST_Constant (concat_str , NULL , elem -> lineno , elem -> col_offset ,
2463
+ last_elem -> end_lineno , last_elem -> end_col_offset , p -> arena );
2464
+ if (elem == NULL ) {
2465
+ Py_DECREF (concat_str );
2466
+ return NULL ;
2404
2467
}
2405
2468
}
2469
+
2470
+ asdl_seq_SET (values , current_pos ++ , elem );
2406
2471
}
2407
2472
2473
+ if (!f_string_found ) {
2474
+ assert (n_elements == 1 );
2475
+ expr_ty elem = asdl_seq_GET (values , 0 );
2476
+ assert (elem -> kind == Constant_kind );
2477
+ return elem ;
2478
+ }
2479
+
2408
2480
return _PyAST_JoinedStr (values , lineno , col_offset , end_lineno , end_col_offset , p -> arena );
2409
2481
}
2410
2482
0 commit comments