Best way to evaluate boolean expressions from strings?

Peter Otten __peter__ at web.de
Mon Apr 27 19:30:31 CEST 2009


Gustavo Narea wrote:

> I need to evaluate boolean expressions like "foo == 1" or "foo ==1 and
> (bar > 2 or bar == 0)" which are defined as strings (in a database or
> a plain text file, for example). How would you achieve this?
> 
> These expressions will contain placeholders for Python objects (like
> "foo" and "bar" in the examples above). Also, the Python objects that
> will get injected in the expression will support at least one of the
> following operations: "==", "!=", ">", "<", ">=", "<=", "&", "|",
> "in".
> 
> I don't need the ability to import modules, define classes, define
> functions, etc. I just need to evaluate boolean expressions defined as
> strings (using the Python syntax is fine, or even desirable).
> 
> Here's a complete example:
> 
> I have the "user_ip" and "valid_ips" placeholders defined in Python as
> follows:
> """
> user_ip = '111.111.111.111'
> 
> class IPCollection(object):
>     def __init__(self, *valid_ips):
>         self.valid_ips = valid_ips
>     def __contains__(self, value):
>         return value in self.valid_ips
> 
> valid_ips = IPCollection('222.222.222.222', '111.111.111.111')
> """
> 
> So the following boolean expressions given as strings should be
> evaluated as:
>  * "user_ip == '127.0.0.1'"  --->  False
>  * "user_ip == '127.0.0.1' or user_ip in valid_ips"  --->  True
>  * "user_ip not in valid_ips" ---> False
> 
> That's it. How would you deal with this? I would love to re-use
> existing stuff as much as possible, that works in Python 2.4-2.6 and
> also that has a simple syntax (these expressions may not be written by
> technical people; hence I'm not sure about using TALES).

exprs = [
    "user_ip == '127.0.0.1'",
    "user_ip == '127.0.0.1' or user_ip in valid_ips",
    "user_ip not in valid_ips"]
for expr in exprs:
    print expr, "-->", eval(expr)

Be warned that a malicious user can make your program execute arbitrary
python code; if you put the input form for expressions on the internet
you're toast.

Peter



More information about the Python-list mailing list