Bugs item #1153622, was opened at 2005-02-28 17:48
Message generated for change (Comment added) made by yorick
You can respond by visiting: 
https://sourceforge.net/tracker/?func=detail&atid=105470&aid=1153622&group_id=5470

Category: Parser/Compiler
Group: Python 2.4
Status: Open
Resolution: None
Priority: 5
Submitted By: Mattias Engdegård (yorick)
Assigned to: Nobody/Anonymous (nobody)
Summary: eval does not bind variables in lambda bodies correctly

Initial Comment:
eval() does not bind variables in lambda expressions
correctly:

>>>def f(g): return eval('lambda x: g(x)')
>>>f(lambda y: y * 2)(17)
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
  File "<string>", line 1, in <lambda>
NameError: global name 'g' is not defined

The docs say this about eval():

# If both dictionaries are omitted, the expression is
# executed in the environment where eval is called.

and using plain local variables work as expected:

>>>def h(d): return eval('d(10)')
>>>h(lambda y: y * 2)
20

Also, if locals() is presented as the global dict to
eval(), it works:

>>>def f(g): return eval('lambda x: g(x)', locals(),
locals())
>>>f(lambda y: y * 2)(17)
34

but this does not allow the expression to reference
global variables of course.


----------------------------------------------------------------------

>Comment By: Mattias Engdegård (yorick)
Date: 2005-03-01 10:11

Message:
Logged In: YES 
user_id=432579

>Variables in Python functions are resolved 
>when the function is *called*, not when it is defined.

I'm not sure what you mean by that, since Python obeys
lexical scoping, not dynamic.Consider:

def f(x): lambda y: x + y

When the inner lambda expression above is evaluated, x
inside the lambda body is bound to the parameter of the call
of f, even if x+y is not evaluated until that function is
called.
So since

def f(x): return eval('x')

fetches its definition of x from the lexical variable x, why
shouldn't

def f(g): return eval('lambda x: g(x)')

fetch its definition of g from the lexical variable g? A
lambda expression is just a way of delaying evaluation,
*not* delaying how variables are bound --- this is done
immediately.


----------------------------------------------------------------------

Comment By: Terry J. Reedy (tjreedy)
Date: 2005-03-01 06:30

Message:
Logged In: YES 
user_id=593130

I am 99.5% sure that this is 'invalid' (a Resolution category) and 
should be closed.  With the default environment, eval('x') is the 
same as unquoted x.  Variables in Python functions are resolved 
when the function is *called*, not when it is defined.  There is no 
resolution for g in the default globals.  Eval does not change this.  
The NameError is exactly correct.

----------------------------------------------------------------------

You can respond by visiting: 
https://sourceforge.net/tracker/?func=detail&atid=105470&aid=1153622&group_id=5470
_______________________________________________
Python-bugs-list mailing list 
Unsubscribe: 
http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com

Reply via email to