Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

eval modifies passed dict

1 view
Skip to first unread message

Janto Dreijer

unread,
Apr 14, 2008, 11:23:25 AM4/14/08
to
It seems eval is modifying the passed in locals/globals. This is
behaviour I did not expect and is really messing up my web.py app.

Python 2.5.1 (r251:54863, Mar 7 2008, 04:10:12)
[GCC 4.1.3 20070929 (prerelease) (Ubuntu 4.1.2-16ubuntu2)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> d = dict(a=1)
>>> d.keys()
['a']
>>> eval("a", d)
1
>>> d.keys()
['a', '__builtins__']

That can't be right.

Regards
Janto

colas....@gmail.com

unread,
Apr 14, 2008, 11:48:26 AM4/14/08
to

From the documentation of eval[1]
"If the globals dictionary is present and lacks '__builtins__', the
current globals are copied into globals before expression is parsed."

[1]http://docs.python.org/lib/built-in-funcs.html

Janto Dreijer

unread,
Apr 14, 2008, 11:52:38 AM4/14/08
to

Thanks!

I'll take it to the webpy group as one of their methods unexpectedly
propagates this effect.

Janto

Arnaud Delobelle

unread,
Apr 14, 2008, 11:55:35 AM4/14/08
to
On Apr 14, 4:23 pm, Janto Dreijer <jan...@gmail.com> wrote:
> It seems eval is modifying the passed in locals/globals. This is
> behaviour I did not expect and is really messing up my web.py app.

Reading the documentation would be a good start:

From http://docs.python.org/lib/built-in-funcs.html:

eval( expression[, globals[, locals]])
The arguments are a string and optional globals and locals. If
provided, globals must be a dictionary. If provided, locals can be any
mapping object. Changed in version 2.4: formerly locals was required
to be a dictionary.
The expression argument is parsed and evaluated as a Python expression
(technically speaking, a condition list) using the globals and locals
dictionaries as global and local name space. If the globals dictionary


is present and lacks '__builtins__', the current globals are copied
into globals before expression is parsed.

--
Arnaud

Duncan Booth

unread,
Apr 14, 2008, 12:05:23 PM4/14/08
to
Janto Dreijer <jan...@gmail.com> wrote:

That can exactly be right.

Python always expects a global called '__builtins__'. If it isn't in the
dict you pass to eval to use for globals it will be added. You may, of
course, initialise it yourself if you don't want your script to have
access to all of the standard globals.

The current document is (I think) wrong or at the least misleading. It
says:

> If the globals dictionary is present and lacks '__builtins__', the
> current globals are copied into globals before expression is parsed.

I think it should say:

> If the globals dictionary is present and lacks '__builtins__', the

> current value of __builtins__ is added to globals before expression
> is parsed.

i.e. only a single variable is assigned, other globals aren't copied.

colas....@gmail.com

unread,
Apr 14, 2008, 12:28:22 PM4/14/08
to
On 14 avr, 18:05, Duncan Booth <duncan.bo...@invalid.invalid> wrote:
> Janto Dreijer <jan...@gmail.com> wrote:
> > It seems eval is modifying the passed in locals/globals. This is
> > behaviour I did not expect and is really messing up my web.py app.
>
> > Python 2.5.1 (r251:54863, Mar 7 2008, 04:10:12)
> > [GCC 4.1.3 20070929 (prerelease) (Ubuntu 4.1.2-16ubuntu2)] on linux2
> > Type "help", "copyright", "credits" or "license" for more information.
> >>>> d = dict(a=1)
> >>>> d.keys()
> > ['a']
> >>>> eval("a", d)
> > 1
> >>>> d.keys()
> > ['a', '__builtins__']
>
> > That can't be right.
>
> That can exactly be right.
>
> The current document is (I think) wrong or at the least misleading. It
> says:
>
> > If the globals dictionary is present and lacks '__builtins__', the
> > current globals are copied into globals before expression is parsed.
>
> I think it should say:
>
> > If the globals dictionary is present and lacks '__builtins__', the
> > current value of __builtins__ is added to globals before expression
> > is parsed.
>
> i.e. only a single variable is assigned, other globals aren't copied.

Indeed:

Python 2.5.1 (r251:54863, Mar 7 2008, 03:39:23)


[GCC 4.1.3 20070929 (prerelease) (Ubuntu 4.1.2-16ubuntu2)] on linux2
Type "help", "copyright", "credits" or "license" for more information.

>>> globals().keys()
['__builtins__', '__name__', '__doc__']
>>> b = 2
>>> d = {'a': 1}

0 new messages