Terry J. Reedy added the comment:
I suppose you could say that I kicked that particular can over to the class doc
;-).
The fundamental problem with exec is that it is at least as complicated as
Python, since it executes any legal python code, and in fact is even more
complicated* because there are various possible relationships with the calling
context. Moreover, it always returns None, so that *any* effect is a
side-effect, which tends to be 'magical'.
* For one thing, people can write and run normal python code without knowing
that a = b (and other binding statements, like import) at module scope means
locals()['a'] rather than globals()['a']. At module scope, there are the same
because globals() is locals(). Within exec'ed code, they may not be the same
thing even for 'top level' code. This is exactly what tripped up Anatoly in his
example with the import.
I am thinking that a short How To Exec() might be a good idea, since a real
explanation is too much for even a half-page entry in the built-ins chapter.
Note: the following doc statement "Be aware that the return and yield
statements may not be used outside of function definitions" needs to have
nonlocal added.
>>> nonlocal a
SyntaxError: nonlocal declaration not allowed at module level
>>> exec('nonlocal a')
Traceback (most recent call last):
File "<pyshell#19>", line 1, in <module>
exec('nonlocal a')
File "<string>", line None
SyntaxError: nonlocal declaration not allowed at module level
>>> def f(): exec('nonlocal a')
f()
...
SyntaxError: nonlocal declaration not allowed at module level
This again points to why exec can be confusing. compile() considers the string
it compiles to be top-level code without any surrounding context. However,
exec() enables one to run 'top level' code with different globals and locals.
There is no exact precedent for this in normal operation. The closest is
execution of code within a class statement (before the type(name, dic, bases)
part). But even that is not absolutely the same for nonlocal (though this could
be the only exception ;-).
>>> >>> class C: nonlocal a
SyntaxError: no binding for nonlocal 'a' found
A different error here (arguably not the best) -- the same as
>>> def f(): nonlocal a
SyntaxError: no binding for nonlocal 'a' found
----------
_______________________________________
Python tracker <[email protected]>
<http://bugs.python.org/issue16781>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe:
http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com