
[Andrew Koenig]
Almost. What I really want is for it to be possible to determine the binding of every name by inspecting the source text of the program. Right now, it is often possible to do so, but sometimes it isn't.
Local names are always determined at compile-time in Python. What you can't always determine is whether a non-local (to any enclosing scope) name will end up getting resolved from the module globals or from __builtin__. The runtime error in: def f(): y = x x = 1 f() doesn't occur because Python doesn't know "x" is local to "f" at compile-time (it does know that), it's because Python's compiler doesn't do any flow analysis to detect potential use-before-definition. Instead the runtime initalizes locals to a special "not bound yet" value that the LOAD_FAST (really "load local") opcode special-cases. Note that this is quite unlike Scheme, in which declaration must appear before use (ignoring fancy letrec cases), and declaration must also supply an initial binding (Scheme has no "unbound local" problem because there's no way to create an uninitialized local).