[Python-ideas] String interpolation for all literal strings

Wes Turner wes.turner at gmail.com
Fri Aug 7 14:38:15 CEST 2015


On Fri, Aug 7, 2015 at 7:31 AM, Nick Coghlan <ncoghlan at gmail.com> wrote:

> On 7 August 2015 at 22:12, Eric V. Smith <eric at trueblade.com> wrote:
> > On 8/7/2015 7:52 AM, Eric V. Smith wrote:
> >> So (reverting to Python syntax, with the f-string syntax), in addition
> >> to converting directly to a string, there's a way to go from:
> >>
> >> f'abc{expr1:spec1}def{expr2:spec2}ghi'
> >>
> >> to:
> >>
> >> ('abc{0:spec1}def{1:spec2}ghi', (value-of-expr1, value-of-expr2))
> >>
> >> The general idea is that you now have access to an i18n-able string, and
> >> the values of the embedded expressions as they were evaluated "in situ"
> >> where the f-string literal was present in the source code.
> >> Y
> >> ou can imagine the f-string above evaluating to a call to:
> >>
> >> __interpolate__('abc{0:spec1}def{1:spec2}ghi', (value-of-expr1,
> >> value-of-expr2))
> >>
> >> The default implementation of __interpolate__ would be:
> >>
> >> def __interpolate__(fmt_str, values):
> >>     return fmt_str.format(*values)
> >
> > I should add that it's unfortunate that this builds a string for
> > str.format() to use. The f-string ast generator goes through a lot of
> > hassle to parse the f-string and extract the parts. For it to then build
> > another string that str.format would have to immediately parse again
> > seems like a waste.
> >
> > My current implementation of f-strings would take the original f-string
> > above and convert it to:
> >
> > ''.join(['abc', expr1.__format__('spec1'), 'def',
> >          expr2.__format__(spec2), 'ghi'])
> >
> > Which avoids re-parsing anything: it's just normal function calls.
> > Making __interpolate__ take a tuple of literals and a tuple of (value,
> > fmt_str) tuples seems like giant hassle to internationalize, but it
> > would be more efficient in the normal case.
>
> Perhaps we could use a variant of the string.Formatter.parse iterator
> format:
> https://docs.python.org/3/library/string.html#string.Formatter.parse
> ?
>
> If the first arg was a pre-parsed format_iter rather than a format
> string, then the default interpolator might look something like:
>
>     _converter = string.Formatter().convert_field
>
>     def __interpolate__(format_iter, expressions, values):
>         template_parts = []
>         # field_num, rather than field_name, for speed reasons
>         for literal_text, field_num, format_spec, conversion in
> format_iter:
>             template_parts.append(literal_text)
>             if field_num is not None:
>                 value = values[field_num]
>                 if conversion:
>                     value = _converter(value, conversion)
>                 field_str = format(value, format_spec)
>                 template_parts.append(field_str)
>         return "".join(template_parts)
>

Would __interpolate__ then be an operator / protocol,
or just a method of an r-string?

Benefits / (other use cases):
* implicit/explicit [shell,shlex,[SQL, SPARQL]] quoting (e.g. "" +
repr(x)[1:-1] + "")



>
> My last il8n example called string.Formatter.parse() anyway, so it
> could readily be adapted to this model.
>
> Cheers,
> Nick.
>
> --
> Nick Coghlan   |   ncoghlan at gmail.com   |   Brisbane, Australia
> _______________________________________________
> Python-ideas mailing list
> Python-ideas at python.org
> https://mail.python.org/mailman/listinfo/python-ideas
> Code of Conduct: http://python.org/psf/codeofconduct/
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-ideas/attachments/20150807/8c204207/attachment-0001.html>


More information about the Python-ideas mailing list