why? __builtins__ key added from eval

Lie Ryan lie.1296 at gmail.com
Thu Oct 2 15:48:57 EDT 2008


On Tue, 30 Sep 2008 16:04:34 -0500, William Purcell wrote:

> I want to use eval to evaluate wx.TextCtrl inputs. How can I keep python
> from adding the __builtins__ key to mydict when I use it with eval?
> Other wise I have to __delitem__('__builtins__') everytime I use eval?
> 
>>>> mydict = {'a':2,'b':3}
>>>> eval('a*b',mydict)
> 6
>>>> mydict
> {'a': 2, '__builtins__': {'IndexError': <type 'exceptions.IndexError'>,
> ...(I'll spare you the rest)...}, 'b': 3}
> 
> Also, how come eval has this behavior? Is it desirable?
> 
> -Bill

when you pass mydict, it is used as the global variables in the eval, 
right? Then, you passed a code to eval('...', mydict), sometimes you 
might create global variable inside eval, and you want to see the value 
of that inner global, that's why python modified mydict as a side-effect.

Then what is __builtins__ doing there? Because when eval created an 
environment for the code to run, python interpreter need to define things 
that it used by itself. The __builtins__ contained all built-in names 
that is always available in python (python have to store it somewhere, 
the built-in names couldn't be bound by magic, right?). 

You could remove the builtin if you don't think it is necessary for you. 
Or you could do "dictionary comprehension" that collects only names you 
require (actually use generator comprehension then do a dict() 
conversion, dictionary comprehension was rejected some time ago)

e.g.:
newdict = dict(k, v for k, v in mydict.iteritems() if k in ['a', 'b'])

or you could make a copy of mydict before passing it to eval.

Last note: eval is evil. (no pun intended)




More information about the Python-list mailing list