[Python-ideas] Draft PEP on string interpolation

Eric V. Smith eric at trueblade.com
Mon Aug 24 17:14:53 CEST 2015


On 08/23/2015 09:13 PM, Guido van Rossum wrote:
> But for i-strings, I think it would be good if we could gather more
> actual experience using them. Every potential use case brought up for
> these so far (translation, html/shell/sql quoting) feels like there's a
> lot of work needing to be done to see if the idea is actually viable
> there. It would be a shame if we added all the (considerable!) machinery
> for i-strings and all we got was yet another way to do it
> (https://xkcd.com/927/), without killing at least one competing approach
> (similar to the way .format() has failed to replace %).
> 
> It's tough to envision how we could gather more experience with
> i-strings *without* building them into the language, but I'm really
> hesitant to add them without more experience. (This is the "new on the
> job market" paradox. :-) Maybe they could be emulated using a function
> call that uses sys._getframe() under the covers? Or maybe it's possible
> to cook up an experiment using other syntax hooks? E.g. the coding hack
> used in pyxl (https://github.com/dropbox/pyxl).[1]


I hope you don't mind that I borrowed the keys to the time machine. I'm
using the implementation of _string.formatter_parser() that I added for
implementing string.Formatter:

---8<---------------------------------------------
import sys
import _string

class i:
    def __init__(self, s):
        self.s = s
        locals = sys._getframe(1).f_locals
        globals = sys._getframe(1).f_globals
        self.values = {}
        # evaluate the expressions
        for literal, expr, format_spec, conversion in \
                _string.formatter_parser(self.s):
            if expr:
                value = eval(expr, locals, globals)
                self.values[expr] = value

    def __str__(self):
        result = []
        for literal, expr, format_spec, conversion in \
                _string.formatter_parser(self.s):
            result.append(literal)
            if expr:
                value = self.values[expr]
                result.append(value.__format__(format_spec))
        return ''.join(result)
---8<---------------------------------------------

So now, instead of i"x={x}", we say i("x={x}").

Let's use it with str:

>>> x = i('Version in caps {sys.version[0:7].upper()}')
>>> x
<__main__.i object at 0x7f1653311e90>
>>> str(x)
'Version in caps 3.6.0A0'


Cool. Now let's whip up a simple i18n example:

>>> def gettext(s):
...     # Our complicated string lookup
...     if s == 'My name is {name}, my dog is {dog}':
...         return 'Mi pero es {dog}, y mi nombre es {name}'
...     return s
...
>>> def _(istring):
...     result = []
...     # do the gettext lookup
...     s = gettext(istring.s)
...     # use the values from our original istring,
...     #  but the literals and ordering from our
...     #  looked-up string
...     for literal, expr, format_spec, conversion in \
...             _string.formatter_parser(s):
...         result.append(literal)
...         if expr is not None:
...             result.append(istring.values[expr])
...     return ''.join(result)
...
>>> name = 'Eric'
>>> dog = 'Misty'
>>> x = i('My name is {name}, my dog is {dog}')
>>> str(x)
'My name is Eric, my dog is Misty'
>>> _(x)
'Mi pero es Misty, y mi nombre es Eric'
>>>

That should be enough to play with i-strings in logging, sql, xml, etc.

Several things should be addressed: hiding the call to
_string.formatter_parse inside the 'i' class, for example. And of course
don't use sys._getframe. But the ideas are all there.

I can't swear that _string.formatter_parser will parse all known
expressions, since that's not what it was designed to do. It will likely
fail with expressions that contain strings and braces, for example. I
haven't really checked. But hey, what do you want for free?

With a slight tweak, this code even works with 2.7: replace
"_string.formatter_parser" with "str._formatter_parser". Unfortunately,
2.7 will then only support very simple expressions. Oh, well.

Enjoy!

Eric.



More information about the Python-ideas mailing list