The Case Against Python 3

Chris Angelico rosuav at gmail.com
Mon Nov 28 20:00:43 EST 2016


On Tue, Nov 29, 2016 at 10:54 AM, Steve D'Aprano
<steve+python at pearwood.info> wrote:
> Now you're just being silly, this isn't "anything", it is a specific design
> decision: something which looks like, and is treated by the tokeniser, as a
> string but is actually a hidden call to eval.
>

This, I think, is the crux. A "hidden eval" is a fundamentally bad
thing. Python 2's input() function is bad for this reason - not
because eval is necessarily evil (there are times when that's the
exact behaviour you want), but because the simple "get text from the
keyboard" function shouldn't conceal an eval of user text.

The solution, IMO, is to treat f-strings as expressions and NOT as
strings. They are no more strings than function calls are:

"###".join(os.system("sh"))

Everything that tokenizes Python code needs to be aware of the
different string prefixes already (eg a raw string literal doesn't end
at the same point as other string literals do), and this should be no
different. The stdlib ast.parse (really a wrapper around compile)
already gets this right:

>>> ast.dump(ast.parse('lambda x,y: f"{x} + {y} = {x+y}"'))
"Module(body=[Expr(value=Lambda(args=arguments(args=[arg(arg='x',
annotation=None), arg(arg='y', annotation=None)], vararg=None,
kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]),
body=JoinedStr(values=[FormattedValue(value=Name(id='x', ctx=Load()),
conversion=-1, format_spec=None), Str(s=' + '),
FormattedValue(value=Name(id='y', ctx=Load()), conversion=-1,
format_spec=None), Str(s=' = '),
FormattedValue(value=BinOp(left=Name(id='x', ctx=Load()), op=Add(),
right=Name(id='y', ctx=Load())), conversion=-1,
format_spec=None)])))])"

So what is it that's trying to read something and is calling an
f-string a mere string?

ChrisA



More information about the Python-list mailing list