Question

I have heard that ast.literal_eval is much safer than eval(), but while changing my code, I am getting 'malformed string/node' errors.

For example:

bar = False
incorrect = {"foo":bar}
correct = {"foo":"bar"}

ast.literal_eval(incorrect) 

returns the error but

ast.literal_eval(correct) 

returns the expected {"foo":"bar"}

Why doesn't the first evaluation return {"foo":False}

Was it helpful?

Solution

Because it is not meant to do that. From the documentation:

Safely evaluate an expression node or a Unicode or Latin-1 encoded string containing a Python expression. The string or node provided may only consist of the following Python literal structures: strings, numbers, tuples, lists, dicts, booleans, and None.

ast.literal_eval and eval are meant to turn a string representation of python code into ...valid python code.

This will not work:

>>> ast.literal_eval({"foo": "bar"})
Traceback (most recent call last):
  File "<input>", line 1, in <module>
  File "/usr/lib/python2.7/ast.py", line 80, in literal_eval
    return _convert(node_or_string)
  File "/usr/lib/python2.7/ast.py", line 79, in _convert
    raise ValueError('malformed string')
ValueError: malformed string <-- Telltale right here.

That is because you already have a valid python structure which you are attempting to evaluate.

If you put quotes around the whole thing instead, it will create a dictionary:

>>> ast.literal_eval('{"foo": "bar"}')
{'foo': 'bar'}

OTHER TIPS

From the documentation on ast.literal_eval:

Safely evaluate an expression node or a Unicode or Latin-1 encoded string containing a Python expression. The string or node provided may only consist of the following Python literal structures: strings, numbers, tuples, lists, dicts, booleans, and None.

This can be used for safely evaluating strings containing Python expressions from untrusted sources without the need to parse the values oneself.

bar is indeed False, but is not literal. literal_eval cannot see variables. It only works with literals.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top