[Python-Dev] PEP 498 (interpolated f-string) tweak

Eric V. Smith eric at trueblade.com
Sat Sep 19 22:53:23 CEST 2015


On 9/19/2015 3:36 PM, Eric V. Smith wrote:
> On 9/19/2015 3:22 PM, Serhiy Storchaka wrote:
>> On 19.09.15 14:03, Eric V. Smith wrote:
>>> Instead of calling __format__, I've changed the code generator to call
>>> format(expr1, spec1). As an optimization, I might add special opcodes to
>>> deal with this and string concatenation, but that's for another day (if
>>> ever).
>>
>> Concatenating many strings is not efficient. More efficient way is to
>> use string formatting. Why not translate f-string to
>>
>>     'abc%s%sdef%sghi' % (format(expr1, spec1),
>>                          format(repr(expr2), spec2), expr3)
> 
> As the PEP says, the expression with '+' is illustrative, not how it's
> actually implemented. The implementation currently uses ''.join,
> although I reserve the right to change it.

I should also note: an earlier version of the PEP showed the ''.join()
version of the equivalent code, but the feedback was that it was
confusing, and the '+' version was easier to understand.

And another reason that I don't use %-formatting or ''.format() as the
implementation is for performance: the parser spends a lot of effort to
parse the f-string. To then put it back together and have ''.format()
immediately re-parse it didn't make much sense. And I'm not convinced
there aren't edge cases where the f-string parser and the ''.format()
parse differ, especially when dealing with nested format_specs with
funky characters.

Instead, I generate two additional AST nodes: ast.FormattedValue and
ast.JoinedStr. JoinedStr just has list of string expressions which get
joined together (as I said: currently using ''.join()). FormattedValue
contains the expression and its optional conversion character and
optional format_spec, which get formatted into a string (currently using
the builtin format()).

Eric.



More information about the Python-Dev mailing list