Best way to evaluate boolean expressions from strings?
Peter Otten
__peter__ at web.de
Mon Apr 27 13:30:31 EDT 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