[Python-ideas] Briefer string format

Guido van Rossum guido at python.org
Tue Jul 21 08:05:17 CEST 2015


On Mon, Jul 20, 2015 at 9:52 PM, Eric V. Smith <eric at trueblade.com> wrote:

> On 07/20/2015 03:22 PM, Guido van Rossum wrote:
>
> >     > So the idea is that
> >     > f'x:{a.x} y:{y}'
> >     > would translate to bytecode that does:
> >     > 'x:{a.x} y:{y}'.format(a=a, y=y)
> >     >
> >     > Correct?
> >
> >     That's exactly what I had in mind, at least. Indexing is supported
> >     in format strings too, so f'{a[1]}' also becomes
> >     '{a[1]}'.format(a=a), but I don't think there are any other strange
> >     cases here. I would vote for f'{}' or f'{0}' to just be a
> SyntaxError.
> >
> >
> > +1 on that last sentence. But I prefer a slightly different way of
> > implementing (see my reply to Eric).
>
> Right. And following up here to that email:
>
> > I was more thinking of translating that specific example to
> >
> >     'x:{} y:{}'.format(a.x, y)
> >
> > which avoids some of the issues your example is trying to clarify.
>
> That is better. The trick is converting the string "a.x" to the
> expression a.x, which should be easy enough at compile time.
>

I wonder if we could let the parser do this? consider f'x:{ as one token
and so on?


> > It would still probably be best to limit the syntax inside {} to exactly
> > what regular .format() supports, to avoid confusing users.
>
> The expressions supported by .format() are limited to attribute access
> and "indexing". We just need to enforce that same restriction here.
>
> > Though the consistency argument can be played both ways -- supporting
> > absolutely anything that is a valid expression would be more consistent
> > with other places where expressions occur. E.g. in principle we could
> > support operators and function calls here.
>
> It would be easiest to not restrict the expressions, but then we'd have
> to maintain that restriction in two places.
>
> And now that I think about it, it's somewhat more complex than just
> expanding the expression. In .format(), this:
> '{a[0]}{b[c]}'
> is evaluated roughly as
> format(a[0]) + format(b['c'])
>

Oooh, this is very unfortunate. I cannot support this. Treating b[c] as
b['c'] in a "real" format string is one way, but treating it that way in an
expression is just too weird.


> So to be consistent with .format(), we have to fully parse at least the
> indexing out to see if it looks like a constant integer or a string.
>
> So given that, I think we should just support what .format() allows,
> since it's really not quite as simple as "evaluate the expression inside
> the braces".
>

Alas. And this is probably why we don't already have this feature.


> > Not sure what you mean by "implicit merging" -- if you mean literal
> > concatenation (e.g. 'foo' "bar" == 'foobar') then I think it should be
> > allowed, just like we support mixing quotes and r''.
>
> If I understand it, I think the concern is:
>
> f'{a}{b}' 'foo{}' f'{c}{d}'
>
> would need to become:
> f'{a}{b}foo{{}}{c}{d}'
>
> So you have to escape the braces in non-f-strings when merging strings
> and any of them are f-strings, and make the result an f-string. But I
> think that's the only complication.
>

That's possible; another possibility would be to just have multiple
.format() calls (one per f'...') and use the + operator to concatenate the
pieces.

-- 
--Guido van Rossum (python.org/~guido)
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-ideas/attachments/20150721/82fb5a34/attachment-0001.html>


More information about the Python-ideas mailing list