Why does the literal evaluation of 5 * 7
fail, while 5 + 7
doesn't?
import ast
print(ast.literal_eval('5 + 7'))
# -> 12
print(ast.literal_eval('5 * 7'))
# ->
Traceback (most recent call last):
...
ValueError: malformed node or string: <_ast.BinOp object at ...>
The documentation doesn't explain this.
I found that problem after answering this question on SO: Getting the result of a string.
ast. literal_eval() The ast module helps Python applications to process trees of the Python abstract syntax grammar. The literal_eval safely evaluate an expression node or a string containing a Python literal or container display.
The ast. literal_eval method can safely evaluate strings containing Python values from unknown sources without us having to parse the values. However, complex expressions involving indexing or operators cannot be evaluated using this function.
If you see this error, it usually means the the client is not able to transform the string you wrote to the character set acceptable to the Firebird server. Here's a short explanation how this works: In your client program, you type in some text, which is then shown on the screen.
ast.literal_eval()
accepts +
in the evaluated data because 5+2j
(complex number*) are valid literals. The same applies to -
. To keep the code simple, no attempt is made to exclude +
or -
as a binary operators.
No other operators are allowed; the function is supposed to only accept literals, not expressions.
In other words, that 5 + 7
works is a bug, but one that is hard to fix without breaking support for constructing complex numbers. The implementation limits the use to operands that are numbers, unary +
and -
, or other binary operators (so you can't use these to concatenate lists or produce a set difference).
Also see several related Python bugtracker entries: #25335 ast.literal_eval fails to parse numbers with leading "+", #22525 ast.literal_eval() doesn't do what the documentation says and #4907 ast.literal_eval does not properly handled complex numbers
* Technically speaking, 2j
is a valid literal; Python parses 5+2j
as int(5) binop(+) complex(0, 2)
, and only later produces a complex(5, 2)
object from the result, when actually executing the addition.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With