Simple and safe evaluator

bvdp bob at mellowood.ca
Mon Jun 16 22:47:30 CEST 2008


Okay guys. I have the _ast based safe eval installed and working in my 
program. It appears to be working just fine. Thanks for the help.

Now, a few more questions:

1. I see that _ast is a 2.5 module?? So, for folks using my code with 
<2.5 I could do something like this:

# I've got some imports here to look after the error() and warning() 
funcs ....

emsg_done = 0
etx = ""

def unsafe_eval(s):
     """ safe eval for < python 2.5 (lacks _ast) """
     global emsg_done
     if not emsg_done:
         warning("You are using an unsafe eval() function. Please 
upgrade to Python version 2.5 or greater.")
         emsg_done=1
    # need error trap here as well ...
     return eval(s, {"__builtins__":None}, {} )

def safe_eval(text):
     "similar to eval, but only works on numerical values."
     global etx
     try:
         ast = compile(text, "<string>", 'eval', _ast.PyCF_ONLY_AST)
     except:
         error("Expression error in '%s'" % text)
     etx = text   # for error reporting, bvdp
     return _traverse(ast.body)


try:
     import _ast
     num_eval = safe_eval
except:
     num_eval = unsafe_eval

# rest of matt's ast code follows.

Which appears to do the following: if there isn't an _ast module we just 
define an alternate, not-so-safe, function and warn the user; otherwise 
we use the safe version. I'm a bit uncomfortable with the import _ast 
being after the function which uses the code, but it seems to work.

2. I thought I'd be happy with * / + -, etc. Of course now I want to add 
a few more funcs like int() and sin(). How would I do that?

Thanks. This is looking very nice indeed.

Bob.



More information about the Python-list mailing list