[Python-Dev] Values and objects

Ethan Furman ethan at stoneleaf.us
Sun May 11 07:27:36 CEST 2014


[bringing back on-list]

On 05/10/2014 07:30 PM, Devin Jeanpierre wrote:
> On Sat, May 10, 2014 at 2:38 PM, Ethan Furman <ethan at stoneleaf.us> wrote:
>> On 05/10/2014 02:03 PM, Devin Jeanpierre wrote:
>>>
>>>
>>> spam is referring to a local variable that has not been bound. This is
>>> not an implementation detail.
>>
>> The implementation detail is that in cpython there is a spot already
>> reserved for what will be the 'spam' variable, as opposed to the module
>> level where no such spots are reserved.
>
> I don't know what a "spot reserved" would even mean in  a language
> spec, so sure. But Chris did not bring up the idea of a "reserved
> spot" in the post you were responding to, and I didn't either. Chris
> claimed that Python had unbound variables, you disagreed, and I
> pointed at the docs, which agree with Chris systematically.

Chris was claiming that the exception UnboundLocalError, with complete text of:

UnboundLocalError: local variable 'not_here' referenced before assignment

is saying that the local variable does exist before it is assigned to;  it is my contention that it does not. 
UnboundLocalError came into existence to aid in debugging a specific subclass of errors [1], and the text was chosen for 
that specific purpose.


>>> Because module level variables work differently from local variables.
>>
>> Not by language definition.  There are pythons where modifying function
>> locals works, but the working or not-working is not a language guarantee.
>
> I did make the mistake of saying "locals", when I meant
> "function-level locals". That was wrong.

Um, what other kind of locals are there?


> See https://docs.python.org/3.4/library/exceptions.html#UnboundLocalError
>
> "Raised when a reference is made to a local variable in a function or
> method, but no value has been bound to that variable."

Hmm, looks like a doc-patch is needed.  ;)

Seriously though, error messages are chosen to provide a simple and clear description that will help the user track down 
what went wrong, not for enshrining in exact detail the language semantics.  Would you really rather have:

Traceback (most recent call last):
   File "<stdin>", line 1, in <module>
   File "<stdin>", line 2, in func
UnboundLocalError: the name 'not_here' does not yet exist as you have not yet assigned anything to it so there is 
currently no variable by that name although at some point (in the future of this function, or perhaps in a branch that 
has been passed and did not execute) you will or did assign something to it so it will exist in the future of this 
function or may exist at this point in a future run of this function.

or:

Traceback (most recent call last):
   File "<stdin>", line 1, in <module>
   File "<stdin>", line 2, in func
UnboundLocalError: local variable 'not_here' referenced before assignment


--
~Ethan~


[1] The conditions being that a variable was referenced before is was created, but the text of NameError offered no help 
in figuring that out ("what do you mean it doesn't exist?!?  It's right *there*!")



More information about the Python-Dev mailing list