MSeifert MSeifert -4 years ago 134
Python Question

How to evaluate f strings using ast.literal_eval

When trying to evaluate f-strings with

I get a
ValueError
about a "malformed node or string":

from ast import literal_eval

a = 10

literal_eval("f'test {a}'")


Throws the following error:

---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<...> in <module>()
3 a = 10
4
----> 5 literal_eval("f'test {a}'")

C:\...\lib\ast.py in literal_eval(node_or_string)
83 return left - right
84 raise ValueError('malformed node or string: ' + repr(node))
---> 85 return _convert(node_or_string)
86
87

C:\...\lib\ast.py in _convert(node)
82 else:
83 return left - right
---> 84 raise ValueError('malformed node or string: ' + repr(node))
85 return _convert(node_or_string)
86

ValueError: malformed node or string: <_ast.JoinedStr object at 0x000001F20CE718D0>


However it works without problems for raw or binary strings:

>>> literal_eval("r'This'")
'This'
>>> literal_eval("b'This'")
b'This'


Can I make
ast.literal_eval
work on f-strings? And if yes, what do I need to change?

Answer Source

I'm guessing that the answer here is that you won't be able to do this. An f-string is basically syntactic sugar1 for:

map = {}
map.update(globals())
map.update(locals())
string.format(**map)

The f-string gets evaluated by using the __format__ protocol -- Which means that it isn't a literal. It's an expression. And like any arbitrary expression, it cannot be evaluated safely.

>>> expr = '"boom"'
>>> f'foo{eval(expr)}'
'fooboom'

In the AST, you'll see that it is accomplished via the JoinedStr, Str and FormattedValue ast nodes. Of these, the only one which could be considered a literal is Str.

1This is an understatement -- f-strings also support other types of expressions that aren't just name-lookups or simple things like item access that you can get with vanilla format strings. e.g. They support full-blown function calls.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download