Forum Archive

UnboundLocalError when accessing location.is_authorised() inside function

offtheradar

UnboundLocalError when accessing location.is_authorised() inside function

When I try:

import location

    def get_direction():
        if location.is_authorized():
        #do something

I get an UnboundLocalError: local variable 'location' referenced before assignment.

But the similar code works with other modules e.g:

import time

    def get_time_diff():
        if time.time() > 1234:
        #do something

How can I get around the UnboundLocalError? Importing the location module inside the function works, but I don't want to have to import it within each function that uses location.

Maybe I'm missing something obvious so any suggestions are appreciated!

omz

I can’t reproduce this. Have you tried restarting (i.e. force-quitting) Pythonista?

JonB

This sort of thing can happen when using threads or button actions that use scripts that have been imported, when you run ine sdript, then another so that globals and user modules get cleared...

You may want to post a complete example where this occurs.

dgelessus

If I'm understanding the error message correctly, this doesn't have anything to do with missing globals. If you try to access a global that doesn't exist, you get a NameError. An UnboundLocalError means that you're trying to access a local variable that is currently unassigned.

Short explanation about Python locals - whether a variable in a function is local or global is determined statically at "compile time". If a variable is assigned to in the function, it is always local, even before the assignment. For example the following code will always produce an UnboundLocalError:

var = "global"
def fun():
    print(var) # raises UnboundLocalError("local variable 'var' referenced before assignment")
    var = "local" # var is assigned to in the function, which makes it local - the global variable var is hidden
fun()

My guess is that you're accidentally using location as a variable name later on in the function. Something like this:

import location

def get_direction():
    if location.is_authorized():
        location = location.get_location()
        # ... do stuff with the location ...
    else:
        print("Location access not allowed!")

Because you're assigning to location, every use of location in the function looks up the local variable location - when that happens before it is assigned, you get an UnboundLocalError like the one you posted. The fix for this is to choose a different name for the local variable, so it doesn't conflict with any globals that you want to use.

hlipperjohn

An UnboundLocalError is raised when a local variable is referenced before it has been assigned. In most cases this will occur when trying to modify a local variable before it is actually assigned within the local scope. Python doesn't have variable declarations, so it has to figure out the scope of variables itself. It does so by a simple rule: If there is an assignment to a variable inside a function, that variable is considered local.

Python has lexical scoping by default, which means that although an enclosed scope can access values in its enclosing scope, it cannot modify them (unless they're declared global with the global keyword). A closure binds values in the enclosing environment to names in the local environment. The local environment can then use the bound value, and even reassign that name to something else, but it can't modify the binding in the enclosing environment. UnboundLocalError happend because when python sees an assignment inside a function then it considers that variable as local variable and will not fetch its value from enclosing or global scope when we execute the function. However, to modify a global variable inside a function, you must use the global keyword.