[docs] [issue26225] New misleading wording in execution model documenation

Martin Panter report at bugs.python.org
Sat Jan 30 00:14:19 EST 2016


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 <report at bugs.python.org>
<http://bugs.python.org/issue26225>
_______________________________________


More information about the docs mailing list