I hit a scoping issue today that initially surprised me. It can be readily demonstrated by the following:
def scope():
x = 1
def working():
print x
def broken():
import pdb; pdb.set_trace()
working()
broken()
Python 2.7.12 (default, Jul 1 2016, 15:12:24)
[GCC 5.4.0 20160609] on linux2
Type "help", "copyright", "credits" or "license" for more information.
...
>>> scope()
1
--Return--
> <stdin>(6)broken()->None
(Pdb) x
*** NameError: name 'x' is not defined
Python 3.5.2 (default, Sep 10 2016, 08:21:44)
[GCC 5.4.0 20160609] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> def scope():
...
>>> scope()
1
--Return--
> <stdin>(6)broken()->None
(Pdb) x
*** NameError: name 'x' is not defined
(Pdb)
So it appears a scope will only contain outer-scope values if there's an explicit reference to them at compilation time. This is certainly what appears to happen when looking at the bytecode:
6 0 LOAD_GLOBAL 0 (x)
3 PRINT_ITEM
4 PRINT_NEWLINE
5 LOAD_CONST 0 (None)
8 RETURN_VALUE
Is this an artifact of how Python differentiates between outer & inner scope references by examining the function for bindings?
This does not appear to be explained by the Python scoping rules:
Although scopes are determined statically, they are used dynamically. At any time during execution, there are at least three nested scopes whose namespaces are directly accessible:
- the innermost scope, which is searched first, contains the local names
- the scopes of any enclosing functions, which are searched starting with the nearest enclosing scope, contains non-local, but also non-global names
What I'm trying to understand is the conflict between the two highlighted parts above: scopes are static but the promise of what names are accessible doesn't seem to be upheld.
Specifically, what I'm looking for is official documentation of this explicit behaviour.