[Python-Dev] PEP-498: Literal String Formatting
Steven D'Aprano
steve at pearwood.info
Mon Aug 10 19:26:31 CEST 2015
On Sun, Aug 09, 2015 at 06:54:38PM -0700, David Mertz wrote:
> Which brought to mind a certain thought. While I don't like:
>
> f'My name is {name}, my age next year is {age+1}'
>
> I wouldn't have any similar objection to:
>
> 'My name is {name}, my age next year is {age+1}'.scope_format()
>
> Or
>
> scope_format('My name is {name}, my age next year is {age+1}')
>
> I realize that these could be completely semantically equivalent... but the
> function or method call LOOKS LIKE a runtime operation, while a one letter
> prefix just doesn't look like that (especially to beginners whom I might
> teach).
I fear that this is actually worse than the f-string concept. f-strings,
as far as I understand, are literals. (Well, not exactly literals.) You
cannot say:
# this can't happen (I think?)
expr = 'age + 1'
result = f'blah blah blah {' + expr + '}'
and inject the expression into the f-string. That makes them a little
weaker than eval(), and hence a little safer. But scope_format would
have to be eval in disguise, since it receives a string as argument,
and it can't know where it came from or how it came to be:
# pretend that expr comes from, say, a web form
expr = 'age + 1}{os.system("echo Pwned!") and ""'
result = scope_format(
'My name is {name}, my age next year is {' + expr + '}'
)
It's a dilemma, because I'm completely with you in your discomfort in
having something which looks like a string literal actually be a
function of sorts; but turning it into an actual function makes it more
dangerous, not less.
I think I would be happy with f-strings, or perhaps i-strings if we use
Nick's ideas about internationalisation, and limit what they can
evaluate to name lookups, attribute lookups, and indexing, just like
format().
We can always relax that restriction in the future, if necessary, but
it's a lot harder to tighten it.
--
Steve
More information about the Python-Dev
mailing list