eval vs. exec

Alexander Schmolck a.schmolck at gmx.net
Mon May 27 13:26:35 EDT 2002


Simon Budig <Simon.Budig at unix-ag.org> writes:
Simon Budig <Simon.Budig at unix-ag.org> writes:

> Alexander Schmolck <a.schmolck at gmx.net> wrote:
> > Simon Budig <Simon.Budig at unix-ag.org> writes:
> > 
> > The distiction is quite simple: use eval for expressions and exec for
> > everything else. That of course only works if you know what qualifies as an
> > expression in python :)
> 
> I think I do know what an expression is - what I do not know is
> how to determine the type to use from a string given by an external
> source.

Sorry, I didn't mean to state the obvious, but it seems to be confusing to
many people, especially since assignments can form part of expressions in many
languages.

Well, if all your stuff is exclusively math expressions which can only contain

a) variables and literals
b) operators
c) maybe some (math) function calls
d) assignments

then maybe something like:

re.search('[^=!]=[^=-+]', str)

is enough to find out? 


But I don't see why you need this distinction anyway, since your current
strategy means you don't reduce everything to expressions, so you might as
well also handle the expressions with exec, or not?

Anyway, this all seems to be heading down the wrong track. I'm not completely
clear I understand your problem, but is my assumption right that it basically
is:

  "I have string consisting of a series of assignment statements (possibly 0)
  followed by an expression and I want to return the value of this
  expression?" ?

>From what I understand the proper solution would very likely involve writing a
parser (either by hand or by using something like spark). But if you'd rather
use exec and evals you can just extract the final expression from the string,
along the lines of (untested):

  re.search(r'(?s)\n|(?:;\s*)(.*)$', ').group(1)

and eval that in the namespace in which you executed the rest, which should
give you the result you are after.

However, all the tricks you have to play to make this stuff safe are
presumably more of an effort than parsing it properly, especially since
parsing simple math expressions often comes as example code for parser
generators and is such a common problem that it shouldn't be that hard to find
something canned.


> 
> I think I took quite good care of it by making sure that before I
> eval/exec something the mathdict["__builtins__"] = {}. In the real code

Are you sure that this is guaranteed to be safe? The reference manual would
suggest that only *additional* keys may be inserted by the implementation, but
I'd rather double-check.

> 
> > BTW: this
> > 
> >>       except:
> > 
> > is almost always a bad idea. You should explicitly test for the Errors you are
> > expecting like so: 
> > 
> >          except SyntaxError:
> >          
> > because otherwise bugs you didn't expect might go unnoticed.
> 
> I do know about this, but this is definitely necessary because otherwise
> it would be possible to crash the program via "raise 'foo'".

Sure, but it might still be helpful to have *2* (or more) except clauses: one
that checks for what you reasonably expect might go wrong and a final
"except:" in the body of which you could print a warning or debugging message,
log intrusion attempts etc., at least while you are still developing the code.

> 
> Thanks,
>         Simon

alex



More information about the Python-list mailing list