The question is not why * not accepted, but rather, "why + 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 the imaginary part combined together; the imaginary part is signaled with j . literal_eval therefore 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 much weaker than necessary, it accepts any chain of additions and subtractions until both left and right sides evaluate any number, thus (1 + 3) + 2 + (4 - 5) is still being analyzed, even if it is not a complex constant consisting of the real + imaginary part.
+ and - not accepted unconditionally: if you try to add 2 lists together, this will fail, even if it can parse list literals, and the 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]
source share