Issue36300
Created on 2019-03-15 10:44 by Martin Hosken, last changed 2022-04-11 14:59 by admin. This issue is now closed.
| Messages (6) | |||
|---|---|---|---|
| msg337980 - (view) | Author: Martin Hosken (Martin Hosken) | Date: 2019-03-15 10:44 | |
The following code fails:
>>> lcls = {'w': 100}
>>> eval('[w for x in ("hello", "world")]', None, lcls)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<string>", line 1, in <module>
File "<string>", line 1, in <listcomp>
NameError: name 'w' is not defined
>>> eval('[w, w, w]', None, lcls)
[100, 100, 100]
whereas in python2 it succeeds
>>> lcls = {'w': 100}
>>> eval('[w for x in ("hello", "world")]', None, lcls)
[100, 100]
|
|||
| msg337981 - (view) | Author: Emmanuel Arias (eamanu) * | Date: 2019-03-15 12:01 | |
I test it on 3.7 and 3.8 and have the same problem |
|||
| msg337984 - (view) | Author: Emmanuel Arias (eamanu) * | Date: 2019-03-15 12:44 | |
I don't know if this a bug for py3 or py2 because the the w variable is not defined on the list comprehension context. Maybe the locals on `eval` must be create w on locals context |
|||
| msg338036 - (view) | Author: Terry J. Reedy (terry.reedy) * ![]() |
Date: 2019-03-15 21:11 | |
You example is a list comprehension, but no matter. In 3.x, the value of a comprehension is the result of calling a temporary function. Functions access globals and nonlocals but not non-global locals of surrounding contexts. Class locals are an example of the latter.
>>> class C:
... w = 100
... l = [w for x in ("hello", "world")]
...
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 3, in C
File "<stdin>", line 3, in <listcomp>
NameError: name 'w' is not defined
To see this, one must make sure that the name in question is not also in globals, as it is below.
>>> w = 50
>>> [w for x in ("hello", "world")]
[50, 50]
>>> class C:
... w = 100
... l = [w for x in ("hello", "world")]
...
>>> C.l
[50, 50] # Evaluated global w, not local w.
When one calls eval with separate globals and locals, one is simulating class context. There should be a FAQ entry about this.
|
|||
| msg344948 - (view) | Author: Pekka Klärck (pekka.klarck) | Date: 2019-06-07 14:54 | |
More ways to be bitten by this strange behavior:
>>> d = {'a': 1, 'b': 2}
>>> eval('[x[k] for k in x]', {}, {'x': d})
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<string>", line 1, in <module>
File "<string>", line 1, in <listcomp>
NameError: name 'x' is not defined
>>>
>>> def f():
... x = {'a': 1, 'b': 2}
... return eval('[x[k] for k in x]')
...
>>> f()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 3, in f
File "<string>", line 1, in <module>
File "<string>", line 1, in <listcomp>
NameError: name 'x' is not defined
In both of the above cases changing
eval('[x[k] for k in x]')
to
eval('[v for v in x.values()]')
avoids the problem. There are no problems when using
[x[k] for k in x]
without `eval()` either. I'd prefer this to be changed, but there should at least be a note in the documentation of `eval()` about this.
|
|||
| msg344949 - (view) | Author: Pekka Klärck (pekka.klarck) | Date: 2019-06-07 14:56 | |
I encountered this issue because Robot Framework -- a generic Python based test automation framework -- supports evaluating Python expressions and this issue was reported for us: https://github.com/robotframework/robotframework/issues/3207 |
|||
| History | |||
|---|---|---|---|
| Date | User | Action | Args |
| 2022-04-11 14:59:12 | admin | set | github: 80481 |
| 2019-06-07 14:56:27 | pekka.klarck | set | messages: + msg344949 |
| 2019-06-07 14:54:57 | pekka.klarck | set | nosy:
+ pekka.klarck messages: + msg344948 |
| 2019-03-15 21:11:09 | terry.reedy | set | status: open -> closed title: eval of generator expressions cannot access local variables -> eval of comprehension cannot access local variables |
| 2019-03-15 12:44:49 | eamanu | set | type: behavior messages: + msg337984 versions: + Python 2.7 |
| 2019-03-15 12:01:53 | eamanu | set | nosy:
+ eamanu messages:
+ msg337981 |
| 2019-03-15 10:45:03 | Martin Hosken | set | versions: + Python 3.6 |
| 2019-03-15 10:44:12 | Martin Hosken | create | |
