Brett, your answer is incomplete and misleading in three ways.
It’s not true that exec without a namespace argument doesn’t modify the
local environment. It behaves as Olle7 expects in the global and class
x = 2
exec("x = 1")
print(x) # -> prints 1, not 2
x = 2
exec("x = 999")
print(x) # -> prints 999
With no additional arguments, the exec function defaults to
Secondly, it also works as Olle7 expects inside functions in Python 2.
And thirdly, even if we explicitly pass
locals() to exec, it still
won’t work inside a function in Python3, at least not in CPython. (Other
Python implementations may differ.)
Olle7, the behaviour you see is intentional, it is an optimisation to
help functions run faster. It is not a language feature, but a
limitation of CPython that the local namespace inside a function is
special. Both eval and exec can read variables but exec may not be able
to write variables inside a function. There are notes about this in the
I seem to remember the docs explicitly mentioning that this was an
implementation detail, not a language feature, but I can’t find that
now and don’t have time to go looking.
In any case, from time to time people suggest changing the behaviour to
operate as expected, but such proposals haven’t gone anywhere as yet.