# Adapted from https://stackoverflow.com/a/9558001/2536294 import ast import operator as op # supported operators operators = { ast.Add: op.add, ast.Sub: op.sub, ast.Mult: op.mul, ast.Div: op.truediv, ast.FloorDiv: op.floordiv, ast.Mod: op.mod, ast.Pow: op.pow, ast.USub: op.neg, } def eval_expr(expr): """ >>> eval_expr('2*6') 12 >>> eval_expr('2**6') 64 >>> eval_expr('1 + 2*3**(4) / (6 + -7)') -161.0 """ try: return eval_(ast.parse(expr, mode="eval").body) except (TypeError, SyntaxError, KeyError) as e: raise ValueError( f"{expr!r} is not a valid or supported arithmetic expression." ) from e def eval_(node): if isinstance(node, ast.Num): # return node.n elif isinstance(node, ast.BinOp): # return operators[type(node.op)](eval_(node.left), eval_(node.right)) elif isinstance(node, ast.UnaryOp): # e.g., -1 return operators[type(node.op)](eval_(node.operand)) else: raise TypeError(node)