New submission from Andrew Barnert: In #24129, the wording describing class local bindings in 4.2.2 "Resolution of names" was changed for Python 3.4, 3.5, and 3.6. The new version is a lot clearer for classes--but now it's misleading for `exec`/`eval`.
--- > Class definition blocks and arguments to exec() and eval() are > special in the context of name resolution. A class definition is... ... and then proceeds to explain how class lookup works, without ever mentioning `exec` and `eval`. This implies that they work the same way as classes, but of course that's not true: i = 'global' def f(): i = 'nonlocal' class C: print(i) i = 'local' print(i) f() That prints `global`, then `local`. But with `exec`: i = 'global' def f(): i = 'nonlocal' exec("print(i)\ni = 'local'\nprint(i)\n") f() That prints `nonlocal` then `local`. I think just putting a paragraph break between the first sentence and the rest of the paragraph might be sufficient to avoid the confusion here. Or just removing any mention of `eval` and `exec`. If not, this probably needs a new one-liner paragraph saying something like "Arguments to `exec()` and `eval()` are also special, as described later." --- Meanwhile, if you keep reading, you'll eventually find that `exec` is described in a later section, 4.2.4 "Interaction with dynamic features", but that's _also_ misleading: > The eval() and exec() functions do not have access to the full > environment for resolving names. Names may be resolved in the > local and global namespaces of the caller. Free variables are not > resolved in the nearest enclosing namespace, but in the global > namespace. If that were true, the `exec` example would have printed `global`, right? I'm pretty sure that what's going on here is that `exec` implicitly calls `locals()` (or, rather, the C-API equivalent), which constructs a locals dict on demand, which, only if you're inside a function block, includes not just the currently-bound fast locals, but _also_ the cell_contents of the currently-bound free variables. So, as far as `exec` is concerned, `i` is not an unbound local, or a free variable, but a local, which is bound to the `'nonlocal'` cell value of `i` at the time `exec` was called. Which means the following actually _does_ print `global`: i = 'global' def f(): exec("print(i)\ni = 'local'\nprint(i)\n") i = 'nonlocal' f() I have no idea how to make this clear. Maybe the simplest is to not try to give a full explanation here, and instead punt to the `locals()` function definition? Maybe something like this: > The `eval()` and `exec()` functions do not have access to the full > environment for resolving names, but rather to the approximation of that > environment as constructed by the `locals()` function. Free variables that > are not captured as locals are not resolved in the nearest enclosing > namespace, but in the global... ... and from there, the same as the current paragraph. ---------- assignee: docs@python components: Documentation messages: 259073 nosy: abarnert, docs@python priority: normal severity: normal status: open title: New misleading wording in execution model documenation _______________________________________ 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