Nick Coghlan added the comment:

The "normal rules for name resolution" reference here is referring to the name 
lookup rules as they existed prior to the introduction of lexical scoping for 
functions. It's a dated way of describing it, as the current behaviour of 
functions has now been around long enough that a lot of folks will consider 
*that* normal, and the module, class and exec scoping rules to be the unusual 
case (as levkivskyi has here).

However, I've spent far too many hours staring at CPython compiler internals to 
be able to suggest a helpful rewording that will make sense to folks that 
*haven't* done that, so I'll instead provide the relevant background info to 
see if others can come up with a concise rewording of the reference docs :)

Prior to Python 2.1, Python didn't have closure support, and hence nested 
functions and classes couldn't see variables in outer scopes at all - they 
could see their local scope, the module globals, and the builtins. That changed 
with the introduction of nested scopes as a __future__ import in Python 2.1 and 
the default behaviour in 2.2: https://www.python.org/dev/peps/pep-0227/

As a result of that change, the compiler now keeps track of "function locals" 
at compile time, and *emits different code for references to them*. Where early 
versions of CPython only had LOAD_NAME and LOAD_GLOBAL in the bytecode, these 
days we now also have LOAD_FAST (function local), LOAD_CLOSURE (function local 
referenced as a nonlocal), LOAD_DEREF (function nonlocal) and LOAD_CLASSDEREF 
(class nonlocal). The latter four opcodes will *only* be emitted in a function 
body - they'll never be emitted for module level code (include the bodies of 
module level class definitions). If you attempt to reference a function local 
before a value has been assigned, you'll get UnboundLocalError rather than 
NameError.

The name lookup rules used for execution of class bodies are thus the same ones 
used for the exec() builtin with two namespace arguments: there is a local 
namespace where name assignments happen, and name lookups check the local, 
global and builtin namespaces in that order. The code is executed line by line, 
so if a name is referenced before it has been assigned locally, then it may 
find a global or builtin of that name. Classes that are defined inside a 
function may refer to lexically scoped local variables from the class body, but 
class variables are not themselves visible to function definitions nested 
inside a class scope (i.e. method definitions).

These rules are also used for module level execution and exec() with a single 
namespace argument, except that the local namespace and the global namespace 
refer to the same namespace.

----------

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

Reply via email to