@@ -1067,6 +1067,10 @@ PyCompile_OpcodeStackEffect(int opcode, int oparg)
10671067 return 1 ;
10681068 case GET_YIELD_FROM_ITER :
10691069 return 0 ;
1070+ case FORMAT_VALUE :
1071+ /* If there's a fmt_spec on the stack, we go from 2->1,
1072+ else 1->1. */
1073+ return (oparg & FVS_MASK ) == FVS_HAVE_SPEC ? -1 : 0 ;
10701074 default :
10711075 return PY_INVALID_STACK_EFFECT ;
10721076 }
@@ -3241,83 +3245,47 @@ compiler_joined_str(struct compiler *c, expr_ty e)
32413245 return 1 ;
32423246}
32433247
3244- /* Note that this code uses the builtin functions format(), str(),
3245- repr(), and ascii(). You can break this code, or make it do odd
3246- things, by redefining those functions. */
3248+ /* Used to implement f-strings. Format a single value. */
32473249static int
32483250compiler_formatted_value (struct compiler * c , expr_ty e )
32493251{
3250- PyObject * conversion_name = NULL ;
3251-
3252- static PyObject * format_string ;
3253- static PyObject * str_string ;
3254- static PyObject * repr_string ;
3255- static PyObject * ascii_string ;
3256-
3257- if (!format_string ) {
3258- format_string = PyUnicode_InternFromString ("format" );
3259- if (!format_string )
3260- return 0 ;
3261- }
3262-
3263- if (!str_string ) {
3264- str_string = PyUnicode_InternFromString ("str" );
3265- if (!str_string )
3266- return 0 ;
3267- }
3268-
3269- if (!repr_string ) {
3270- repr_string = PyUnicode_InternFromString ("repr" );
3271- if (!repr_string )
3272- return 0 ;
3273- }
3274- if (!ascii_string ) {
3275- ascii_string = PyUnicode_InternFromString ("ascii" );
3276- if (!ascii_string )
3277- return 0 ;
3278- }
3252+ /* Our oparg encodes 2 pieces of information: the conversion
3253+ character, and whether or not a format_spec was provided.
3254+
3255+ Convert the conversion char to 2 bits:
3256+ None: 000 0x0 FVC_NONE
3257+ !s : 001 0x1 FVC_STR
3258+ !r : 010 0x2 FVC_REPR
3259+ !a : 011 0x3 FVC_ASCII
3260+
3261+ next bit is whether or not we have a format spec:
3262+ yes : 100 0x4
3263+ no : 000 0x0
3264+ */
32793265
3280- ADDOP_NAME ( c , LOAD_GLOBAL , format_string , names ) ;
3266+ int oparg ;
32813267
3282- /* If needed, convert via str, repr, or ascii. */
3283- if (e -> v .FormattedValue .conversion != -1 ) {
3284- switch (e -> v .FormattedValue .conversion ) {
3285- case 's' :
3286- conversion_name = str_string ;
3287- break ;
3288- case 'r' :
3289- conversion_name = repr_string ;
3290- break ;
3291- case 'a' :
3292- conversion_name = ascii_string ;
3293- break ;
3294- default :
3295- PyErr_SetString (PyExc_SystemError ,
3296- "Unrecognized conversion character" );
3297- return 0 ;
3298- }
3299- ADDOP_NAME (c , LOAD_GLOBAL , conversion_name , names );
3300- }
3301-
3302- /* Evaluate the value. */
3268+ /* Evaluate the expression to be formatted. */
33033269 VISIT (c , expr , e -> v .FormattedValue .value );
33043270
3305- /* If needed, convert via str, repr, or ascii. */
3306- if (conversion_name ) {
3307- /* Call the function we previously pushed. */
3308- ADDOP_I (c , CALL_FUNCTION , 1 );
3271+ switch (e -> v .FormattedValue .conversion ) {
3272+ case 's' : oparg = FVC_STR ; break ;
3273+ case 'r' : oparg = FVC_REPR ; break ;
3274+ case 'a' : oparg = FVC_ASCII ; break ;
3275+ case -1 : oparg = FVC_NONE ; break ;
3276+ default :
3277+ PyErr_SetString (PyExc_SystemError ,
3278+ "Unrecognized conversion character" );
3279+ return 0 ;
33093280 }
3310-
3311- /* If we have a format spec, use format(value, format_spec). Otherwise,
3312- use the single argument form. */
33133281 if (e -> v .FormattedValue .format_spec ) {
3282+ /* Evaluate the format spec, and update our opcode arg. */
33143283 VISIT (c , expr , e -> v .FormattedValue .format_spec );
3315- ADDOP_I (c , CALL_FUNCTION , 2 );
3316- } else {
3317- /* No format spec specified, call format(value). */
3318- ADDOP_I (c , CALL_FUNCTION , 1 );
3284+ oparg |= FVS_HAVE_SPEC ;
33193285 }
33203286
3287+ /* And push our opcode and oparg */
3288+ ADDOP_I (c , FORMAT_VALUE , oparg );
33213289 return 1 ;
33223290}
33233291
0 commit comments