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}

Était-ce utile?

La 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'}

Autres conseils

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.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top