[Tutor] Odd behavior with eval, list comps, and name lookup

John bigjohnexpress at gmail.com
Fri Feb 18 01:31:19 CET 2011


I noticed some odd behavior relating to eval(). First, a baseline case for
behavior:

>>> def test():
... x = 5
... return [a for a in range(10) if a == x]
...
>>> test()
[5]

So far so good. Now let's try eval:

>>> c = compile('[a for a in range(10) if a == x]', '', 'single')
>>> eval(c, globals(), {'x': 5})
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "", line 1, in <module>
File "", line 1, in <listcomp>
NameError: global name 'x' is not defined

Looks like 'x' is searched for only among the globals, bypassing the locals.
The same behavior is seen between exec and eval, with and without compile,
and between 3.1.3 and 3.2rc2. Given simpler code without a list comp, the
locals are used just fine:

>>> c = compile('a=5; a==x', '', 'single')
>>> eval(c, {}, {'x': 5})
True

Could anyone help me understand these scoping rules? Thanks.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20110217/bc921fc3/attachment.html>


More information about the Tutor mailing list