[Python-Dev] Improve error message "UnboundLocalError: local variable referenced before assignment"

Terry Reedy tjreedy at udel.edu
Wed Oct 31 22:01:07 CET 2012


This post would have been more appropriate on python-list than 
python-dev. But to answer your implied questions...

On 10/31/2012 3:57 PM, anatoly techtonik wrote:
> Here is the code:
>
> ---[cut]-----------------------------
>
> DEBUG = []
> FONT_NAMES = []

This line has nothing to do with the behavior of the function that 
follows. The error message would be the name if it were deleted.

> def names():
>    if len(DEBUG):
>      print(len(DEBUG))
>    if len(FONT_NAMES):
>      print(len(FONT_NAMES))
>    if len(FONT_NAMES)==0:
>      FONT_NAMES = "query()"

This makes FONT_NAMES a local name *everywhere* within names.

> names()
> ---[cut]-----------------------------
>
> Here is the output:
>
> Traceback (most recent call last):
>    File "globalocal.py", line 13, in <module>
>      names()
>    File "globalocal.py", line 8, in names
>      if len(FONT_NAMES):
> UnboundLocalError: local variable 'FONT_NAMES' referenced before assignment
>
>
> As you may see there is inconsistency between handling of line 6 -
> "if len(DEBUG):" and line 8 - "if len(FONT_NAMES):".

No there is not.

> This is very  magical and hard to troubleshoot.

Names (not 'variables') within a function are deterministically 
classified at compile time as local, nonlocal, or global according to 
declarations and usage *within the function*. This classification has 
nothing to do with names in other namespaces and is done independently 
of other namespaces. The rules are described in the manuals.

> I wonder if this message can be
> improved with a pointer to the concept on when global variables become
> local?

This never happens. Global names stay global (until deleted). They may 
be masked by a local name with the same spelling (as in your example), 
but that is a different issue.

-- 
Terry Jan Reedy



More information about the Python-Dev mailing list