The question is not "why is *
not accepted" but rather "why is +
accepted at all".
ast.literal_eval
can parse literals, but not expressions. However, in Python, complex numbers are not expressed as a single literal value; instead they consist of the real part and imaginary part added together; the imaginary part is signalled with j
. literal_eval
thus needs to support binary +
and -
to support complex number constants such as 1 + 2j
or -3.4e-5 - 1.72e9j
.
In many versions, including Python 3.5, literal_eval
is much more lax than it needs to be - it accepts any chain of additions and subtractions for as long as both the left and right-hand sides evaluate to any number, thus (1 + 3) + 2 + (4 - 5)
is still parsed, even if it is not complex constant consisting of real +
imaginary part.
+
and -
are not accepted unconditionally: if you try to add 2 lists together, it will fail, even though it can parse list literals, and addition is defined for lists:
>>> ast.literal_eval('[1] + [2]')
Traceback (most recent call last):
...
ValueError: malformed node or string: <_ast.BinOp object at 0x7fdddbe785f8>
>>> ast.literal_eval('[1, 2]')
[1, 2]
>>> [1] + [2]
[1, 2]