Following code gives different output in Python2
and in Python3
:
from sys import version
print(version)
def execute(a, st):
b
I'd say it's a bug of python3.
def u():
exec("a=2")
print(locals()['a'])
u()
prints "2".
def u():
exec("a=2")
a=2
print(a)
u()
prints "2".
But
def u():
exec("a=2")
print(locals()['a'])
a=2
u()
fails with
Traceback (most recent call last):
File "", line 1, in
File "", line 3, in u
KeyError: 'a'
--- EDIT --- Another interesting behaviour:
def u():
a=1
l=locals()
exec("a=2")
print(l)
u()
def u():
a=1
l=locals()
exec("a=2")
locals()
print(l)
u()
outputs
{'l': {...}, 'a': 2}
{'l': {...}, 'a': 1}
And also
def u():
l=locals()
exec("a=2")
print(l)
print(locals())
u()
def u():
l=locals()
exec("a=2")
print(l)
print(locals())
a=1
u()
outputs
{'l': {...}, 'a': 2}
{'l': {...}, 'a': 2}
{'l': {...}, 'a': 2}
{'l': {...}}
Apparently, the action of exec
on locals is the following:
exec
and this variable was a local variable, then exec
modifies the internal dictionary (the one returned by locals()
) and does not return it to its original state. A call to locals()
updates the dictionary (as documented in section 2 of python documentation), and the value set within exec
is forgotten.
The need of calling locals()
to update the dictionary is not a bug of python3, because it is documented, but it is not intuitive. Moreover, the fact that modifications of locals within exec
don't change the locals of the function is a documented difference with python2 (the documentation says "Pass an explicit locals dictionary if you need to see effects of the code on locals after function exec() returns"), and I prefer the behaviour of python2.exec
and this variable did not exist before, then exec
modifies the internal dictionary unless the variable is set afterwards. It seems that there is a bug in the way locals()
updates the dictionary ; this bug gives access to the value set within exec
by calling locals()
after exec
.