On Tue, Nov 29, 2016 at 10:54 AM, Steve D'Aprano <steve+pyt...@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 -- https://mail.python.org/mailman/listinfo/python-list