Why doesn't eval of generator expression work with locals?

Robert Kern robert.kern at gmail.com
Tue Jan 27 19:17:16 EST 2009


On 2009-01-27 17:56, Fabio Zadrozny wrote:
> On Tue, Jan 27, 2009 at 9:51 PM, James Mills
> <prologic at shortcircuit.net.au>  wrote:
>> On Wed, Jan 28, 2009 at 9:31 AM, Fabio Zadrozny<fabiofz at gmail.com>  wrote:
>>> Anyone knows why the code below gives an error?
>>>
>>> global_vars = {}
>>> local_vars = {'ar':["foo", "bar"], 'y':"bar"}
>>> print eval('all((x == y for x in ar))', global_vars, local_vars)
>> y is undefined in your generator expression.
>
> Yes... but why? It seems to me like it should be defined (if I put the
> locals in the globals it finds it... seems very weird to me)

I think you can work around your problem by using the same dictionary for both 
locals and globals. The locals/globals distinction is not useful in your 
circumstances. For example, the Python interpreter has these the same:

   >>> globals() is locals()
   True

And that makes the code work:

   >>> y = 'bar'
   >>> ar = ['foo', 'bar']
   >>> all((x==y) for x in ar)
   False
   >>> eval('all((x==y) for x in ar)')
   False

Making locals and globals different emulates a function, where the code will fail:

   >>> del y, ar
   >>> def f():
   ...     y = 'bar'
   ...     ar = ['foo', 'bar']
   ...     print 'Raw genexp:', all((x==y) for x in ar)
   ...     print 'Evaled:', eval('all((x==y) for x in ar)')
   ...
   >>> f()
   Raw genexp: False
   Evaled:
   Traceback (most recent call last):
     File "<stdin>", line 1, in <module>
     File "<stdin>", line 5, in f
     File "<string>", line 1, in <module>
     File "<string>", line 1, in <genexpr>
   NameError: global name 'y' is not defined

Now, the reason that the raw generator expression works inside the function but 
not in the eval() is because the raw generator expression gets lexical scopes 
rather than just the two locals and globals dicts. Lexical scoping is not 
available to the eval() function.

-- 
Robert Kern

"I have come to believe that the whole world is an enigma, a harmless enigma
  that is made terrible by our own mad attempt to interpret it as though it had
  an underlying truth."
   -- Umberto Eco




More information about the Python-list mailing list