@@ -965,17 +965,43 @@ _PyPegen_check_legacy_stmt(Parser *p, expr_ty name) {
965965 return 0 ;
966966}
967967
968- expr_ty
969- _PyPegen_check_fstring_conversion (Parser * p , Token * symbol , expr_ty conv ) {
970- if (symbol -> lineno != conv -> lineno || symbol -> end_col_offset != conv -> col_offset ) {
968+ static ResultTokenWithMetadata *
969+ result_token_with_metadata (Parser * p , void * result , PyObject * metadata )
970+ {
971+ ResultTokenWithMetadata * res = _PyArena_Malloc (p -> arena , sizeof (ResultTokenWithMetadata ));
972+ if (res == NULL ) {
973+ return NULL ;
974+ }
975+ res -> metadata = metadata ;
976+ res -> result = result ;
977+ return res ;
978+ }
979+
980+ ResultTokenWithMetadata *
981+ _PyPegen_check_fstring_conversion (Parser * p , Token * conv_token , expr_ty conv )
982+ {
983+ if (conv_token -> lineno != conv -> lineno || conv_token -> end_col_offset != conv -> col_offset ) {
971984 return RAISE_SYNTAX_ERROR_KNOWN_RANGE (
972- symbol , conv ,
985+ conv_token , conv ,
973986 "f-string: conversion type must come right after the exclamanation mark"
974987 );
975988 }
976- return conv ;
989+ return result_token_with_metadata ( p , conv , conv_token -> metadata ) ;
977990}
978991
992+ ResultTokenWithMetadata *
993+ _PyPegen_setup_full_format_spec (Parser * p , Token * colon , asdl_expr_seq * spec , int lineno , int col_offset ,
994+ int end_lineno , int end_col_offset , PyArena * arena )
995+ {
996+ if (!spec ) {
997+ return NULL ;
998+ }
999+ expr_ty res = _PyAST_JoinedStr (spec , lineno , col_offset , end_lineno , end_col_offset , p -> arena );
1000+ if (!res ) {
1001+ return NULL ;
1002+ }
1003+ return result_token_with_metadata (p , res , colon -> metadata );
1004+ }
9791005
9801006const char *
9811007_PyPegen_get_expr_name (expr_ty e )
@@ -1386,19 +1412,20 @@ expr_ty _PyPegen_constant_from_string(Parser* p, Token* tok) {
13861412 return _PyAST_Constant (s , kind , tok -> lineno , tok -> col_offset , tok -> end_lineno , tok -> end_col_offset , p -> arena );
13871413}
13881414
1389- expr_ty _PyPegen_formatted_value (Parser * p , expr_ty expression , Token * debug , expr_ty conversion ,
1390- expr_ty format , int lineno , int col_offset , int end_lineno , int end_col_offset ,
1391- PyArena * arena ) {
1415+ expr_ty _PyPegen_formatted_value (Parser * p , expr_ty expression , Token * debug , ResultTokenWithMetadata * conversion ,
1416+ ResultTokenWithMetadata * format , Token * closing_brace , int lineno , int col_offset ,
1417+ int end_lineno , int end_col_offset , PyArena * arena ) {
13921418 int conversion_val = -1 ;
13931419 if (conversion != NULL ) {
1394- assert (conversion -> kind == Name_kind );
1395- Py_UCS4 first = PyUnicode_READ_CHAR (conversion -> v .Name .id , 0 );
1420+ expr_ty conversion_expr = (expr_ty ) conversion -> result ;
1421+ assert (conversion_expr -> kind == Name_kind );
1422+ Py_UCS4 first = PyUnicode_READ_CHAR (conversion_expr -> v .Name .id , 0 );
13961423
1397- if (PyUnicode_GET_LENGTH (conversion -> v .Name .id ) > 1 ||
1424+ if (PyUnicode_GET_LENGTH (conversion_expr -> v .Name .id ) > 1 ||
13981425 !(first == 's' || first == 'r' || first == 'a' )) {
1399- RAISE_SYNTAX_ERROR_KNOWN_LOCATION (conversion ,
1426+ RAISE_SYNTAX_ERROR_KNOWN_LOCATION (conversion_expr ,
14001427 "f-string: invalid conversion character %R: expected 's', 'r', or 'a'" ,
1401- conversion -> v .Name .id );
1428+ conversion_expr -> v .Name .id );
14021429 return NULL ;
14031430 }
14041431
@@ -1410,30 +1437,34 @@ expr_ty _PyPegen_formatted_value(Parser *p, expr_ty expression, Token *debug, ex
14101437 }
14111438
14121439 expr_ty formatted_value = _PyAST_FormattedValue (
1413- expression , conversion_val , format ,
1440+ expression , conversion_val , format ? ( expr_ty ) format -> result : NULL ,
14141441 lineno , col_offset , end_lineno ,
14151442 end_col_offset , arena
14161443 );
14171444
14181445 if (debug ) {
14191446 /* Find the non whitespace token after the "=" */
14201447 int debug_end_line , debug_end_offset ;
1448+ PyObject * debug_metadata ;
14211449
14221450 if (conversion ) {
1423- debug_end_line = conversion -> lineno ;
1424- debug_end_offset = conversion -> col_offset ;
1451+ debug_end_line = ((expr_ty ) conversion -> result )-> lineno ;
1452+ debug_end_offset = ((expr_ty ) conversion -> result )-> col_offset ;
1453+ debug_metadata = conversion -> metadata ;
14251454 }
14261455 else if (format ) {
1427- debug_end_line = format -> lineno ;
1428- debug_end_offset = format -> col_offset + 1 ; // HACK: ??
1456+ debug_end_line = ((expr_ty ) format -> result )-> lineno ;
1457+ debug_end_offset = ((expr_ty ) format -> result )-> col_offset + 1 ;
1458+ debug_metadata = format -> metadata ;
14291459 }
14301460 else {
14311461 debug_end_line = end_lineno ;
14321462 debug_end_offset = end_col_offset ;
1463+ debug_metadata = closing_brace -> metadata ;
14331464 }
14341465
1435- expr_ty debug_text = decode_fstring_buffer ( p , lineno , col_offset + 1 ,
1436- debug_end_line , debug_end_offset - 1 );
1466+ expr_ty debug_text = _PyAST_Constant ( debug_metadata , NULL , lineno , col_offset + 1 , debug_end_line ,
1467+ debug_end_offset - 1 , p -> arena );
14371468 if (!debug_text ) {
14381469 return NULL ;
14391470 }
0 commit comments