[Python-Dev] Subtle difference between f-strings and str.format()

Eric V. Smith eric at trueblade.com
Wed Mar 28 16:39:04 EDT 2018


I’d vote #3 as well. 

--
Eric

> On Mar 28, 2018, at 11:27 AM, Serhiy Storchaka <storchaka at gmail.com> wrote:
> 
> There is a subtle semantic difference between str.format() and "equivalent" f-string.
> 
>    '{}{}'.format(a, b)
>    f'{a}{b}'
> 
> In the former case b is evaluated before formatting a. This is equivalent to
> 
>    t1 = a
>    t2 = b
>    t3 = format(t1)
>    t4 = format(t2)
>    r = t3 + t4
> 
> In the latter case a is formatted before evaluating b. This is equivalent to
> 
>    t1 = a
>    t2 = format(t1)
>    t3 = b
>    t4 = format(t3)
>    r = t2 + t4
> 
> In most cases this doesn't matter, but when implement the optimization that transforms the former expression to the the latter one ([1], [2]) we have to make a decision what to do with this difference.
> 
> 1. Keep the exact semantic of str.format() when optimize it. This means that it should be transformed into AST node different from the AST node used for f-strings. Either introduce a new AST node type, or add a boolean flag to JoinedStr.
> 
> 2. Change the semantic of f-strings. Make it closer to the semantic of str.format(): evaluate all subexpressions first than format them. This can be implemented in two ways:
> 
> 2a) Add additional instructions for stack manipulations. This will slow down f-strings.
> 
> 2b) Introduce a new complex opcode that will replace FORMAT_VALUE and BUILD_STRING. This will speed up f-strings.
> 
> 3. Transform str.format() into an f-string with changing semantic, and ignore this change. This is not new. The optimizer already changes semantic. Non-optimized "if a and True:" would call bool(a) twice, but optimized code calls it only once.
> 
> [1] https://bugs.python.org/issue28307
> [2] https://bugs.python.org/issue28308
> 
> _______________________________________________
> Python-Dev mailing list
> Python-Dev at python.org
> https://mail.python.org/mailman/listinfo/python-dev
> Unsubscribe: https://mail.python.org/mailman/options/python-dev/eric%2Ba-python-dev%40trueblade.com



More information about the Python-Dev mailing list