I want an easy way to do a “calculator API” in Python.
Right now I don’t care much about the exact set of features the calculator is going to support.
I want it to receive a string, say "1+1" and return a string with the result, in our case "2".
Is there a way to make eval safe for such a thing?
For a start I would do
env = {}
env["locals"] = None
env["globals"] = None
env["__name__"] = None
env["__file__"] = None
env["__builtins__"] = None
eval(users_str, env)
so that the caller cannot mess with my local variables (or see them).
But I am sure I am overseeing a lot here.
Are eval‘s security issues fixable or are there just too many tiny details to get it working right?
Definitely the latter — a clever hacker will always manage to find a way around your precautions.
If you’re satisfied with plain expressions using elementary-type literals only, use ast.literal_eval — that’s what it’s for! For anything fancier, I recommend a parsing package, such as ply if you’re familiar and comfortable with the classic lexx/yacc approach, or pyparsing for a possibly more Pythonic approach.