[Python-ideas] Draft PEP on string interpolation
Eric V. Smith
eric at trueblade.com
Mon Aug 24 19:10:39 CEST 2015
And because I can't leave well enough alone, here's an improved version.
It includes a little logging example, plus an implementation of
f-strings. Again, using f("") instead of f"".
It might only work with the hg tip (what will be 3.6). I don't have a
3.5 around to test it with. It won't work with 3.3 due to changes in
_string.formatter_parse. It's possible simpler expressions might work,
but I'm not well motivated to try it out.
Eric.
On 08/24/2015 11:55 AM, Eric V. Smith wrote:
> I should have added: this is for i-strings that look like PEP 498's
> f-strings. I'm not trying to jump to conclusions about the syntax: I'm
> just trying to reuse some code, and making i-strings and f-strings look
> like str.format strings allows me to reuse lots of infrastructure (as I
> hope can be seen from this example).
>
> For the final version, we can choose whatever syntax makes sense. I
> would argue for i"Value={value}" (same for f-strings), but if we decide
> to make it something else, I'll live with the decision.
>
> Eric.
>
> On 08/24/2015 11:14 AM, Eric V. Smith wrote:
>> 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.
>>
>> _______________________________________________
>> 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/
>>
>
> _______________________________________________
> 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 --------------
A non-text attachment was scrubbed...
Name: istring.py
Type: text/x-python
Size: 2982 bytes
Desc: not available
URL: <http://mail.python.org/pipermail/python-ideas/attachments/20150824/2ca145f6/attachment.py>
More information about the Python-ideas
mailing list