[Python-Dev] LOAD_NAME & classes

Guido van Rossum guido@python.org
Tue, 23 Apr 2002 11:57:16 -0400

[Steve Holden]
> So, the problem is the implicit local declaration that assumed when
> the compiler detects a binding lower down the function's code than
> the first reference to it, coupled with their function-wide
> scope. It is compounded by the fact that although the analysis is
> performed at compile time the error is only reported at run time.

Well put.

> Might it make more sense to issue a warning at compile time to the
> effect that a variable is being used before it's assigned?

Yes.  Historically (when LOAD_FAST was added) we didn't have a
framework for compile-time warnings, but now we do.

> How completely are (re)bindings detected by the static analysis? Can
> you necessarily guarantee that a LOAD_FAST is always looking at a
> local name? [You'll understand I'm not familiar with the details of
> code generation].

Yes, LOAD_FAST is only emitted if the compiler has decided that it's
a local name, and then there's no exception (though that is exactly
what I contemplated changing earlier in this thread).

> Seems to me the real problem here is explaining (by the
> interpreter's behavior, rather than in the documentation ;-) the
> scope of locals and how a name is determined to be local. It might
> help beginners if there was some really easy way to get a fuller
> explanation of an error message. Not sure how best that could be
> retrofitted, but it's better than code breakage.

I think if they look up UnboundLocalError in the docs they find the
right clues.  Of course it's not necessarily easy to find that bit of
documentation (though Google's first hit is very helpful).

> Unfortunately the scoping rules are now "in the wild", so it's not
> possible to change things too radically without mucho pain for those
> who have already relied on them.

Changing LOAD_FAST so that

    x = 1
    def f():
        print x
	x = 2
	print x

prints 1 followed by 2 instead of raising UnboundLocalError would not
break existing code (except code relying on specific exceptions to be
raised -- but such code is always exempt from non-breakage

--Guido van Rossum (home page: http://www.python.org/~guido/)