I was searching for a safe way to eval simple arithmetic expressions. I'm aware of the difficulties of making eval()
"more safe", but then I learned about ast.literal_eval()
I tried it, with the following example:
>>> ast.literal_eval("1+1")
2
Nice! Now try 1 times 1...
>>> ast.literal_eval("1*1")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/home/jldiaz/miniconda3/lib/python3.6/ast.py", line 85, in literal_eval
return _convert(node_or_string)
File "/home/jldiaz/miniconda3/lib/python3.6/ast.py", line 84, in _convert
raise ValueError('malformed node or string: ' + repr(node))
ValueError: malformed node or string: <_ast.BinOp object at 0x7fac8830aa58>
What does this mean? Malformed string? However it can be parsed without errors:
>>> result = ast.parse("1*1")
>>> ast.dump(result)
'Module(body=[Expr(value=BinOp(left=Num(n=1), op=Mult(), right=Num(n=1)))])'
The AST looks ok, and the operation to perform is Mult()
. However it fails. Apparently it is the operation which is failing, because the AST for the first succesful experiment was identical, only with op=Add()
.
I tried other operations. Division (/
), integer division (//
) and modulo (%
) all fail. Only addition (+
) and substraction (-
) seem to work.
Am I missing something? Surprisingly I was unable to find any information about this problem or the operations supported by ast.literal_eval()