Martin Panter added the comment:

Calling exec() with only one argument is equivalent to exec(..., globals(), 
locals()). It does not create a new scope for names. So an equivalent of your 
three-level example is more like

>>> i = 'global'
>>> def f():
...     i = 'nonlocal'
...     class_locals = dict()
...     exec("print(i)\ni = 'local'\nprint(i)\n", globals(), class_locals)
... 
>>> f()
global
local

If exec() worked like a function rather than a class, the first print(i) would 
trigger an UnboundLocalError instead:

>>> i = 'global'
>>> def f():
...     i = 'nonlocal'
...     def g():
...         print(i)
...         i = 'local'
...     g()
... 
>>> f()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 6, in f
  File "<stdin>", line 4, in g
UnboundLocalError: local variable 'i' referenced before assignment

In your first exec() example, i='nonlocal' is passed to exec() via the default 
locals parameter, and the exec() uses that value rather than deferring to its 
globals. To be a free variable, “i” has to be used but not defined. Even if you 
dropped the “i = 'local' ” assignment, it is still defined via the implicit 
locals parameter.

Your proposal for “Interaction with dynamic features” sounds reasonable.

----------
nosy: +martin.panter

_______________________________________
Python tracker <rep...@bugs.python.org>
<http://bugs.python.org/issue26225>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com

Reply via email to