Mark Dickinson wrote (with interactice prompts removed)
code = """\
y = 3
def f():
return y
. f()
"""
exec code in {} # works fine
exec code in {}, {} # dies with a NameError
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<string>", line 4, in <module>
File "<string>", line 3, in f
NameError: global name 'y' is not defined
I verified that 3.1 (with exec adjusted to be a function) operates the same.
On 5/26/2010 8:51 AM, Nick Coghlan wrote:
>exec with a single argument = module namespace
>exec with two arguments = class namespace
I verified in 3.1 that indenting 'code' and prepending 'class C():\n'
gives the same error and that prepending 'def f():\n' now, with nexted
function namespaces, does not give an error, although it would have been
an error before Python 2.2, when there were no nested function namespaces.
On 5/26/2010 10:03 AM, Colin H wrote:
Thanks for the details on why the observed behaviour occurs - very
clear. My only query would be why this is considered correct? Why is
it running as a class namespace, when it is not a class?
You are expecting that it run as a function namespace (with post 2.2
nesting), when it is not a function. Why is that any better?
Is there any
reason why this is not considered a mistake? Slightly concerned that
this is being considered not a bug because 'it is how it is'.
In original Python, the snippet would have given an error whether you
thought of it as being in a class or function context, which is how
anyone who knew Python then would have expected. Consistency is not a bug.
When nested function namespaces were introduced, the behavior of exec
was left unchanged. Backward compatibility is not a bug.
A change could have been proposed for 3.x, but I do not remember such a
discussion and expect it would have been rejected. One can get the
nested function behavior by doing what I did in the test mentioned
above. One could easily write a nested_exec function to do the wrapping
automatically.
-----
In http://bugs.python.org/issue8824
I suggest that
"In all cases, if the optional parts are omitted, the code is executed
in the current scope. If only globals is provided, it must be a
dictionary, which will be used for both the global and the local
variables. If globals and locals are given, they are used for the
global and local variables, respectively. If provided, locals can be any
mapping object."
be followed by
"If only globals is provided or if onedict is provided as both globals
and locals, the code is executed in a new top-level scope. If different
objects are given as globals and locals, the code is executed as if it
were in a class statement in a new top-level scope."
to make the behavior clearer.
Terry Jan Reedy
_______________________________________________
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe:
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com