Subtle Bug: Variable Shadows Function

Python
If we assign a variable with the same name as a function, even in a conditional statement, the function will be shadowed.
Author

Ziyue Li

Published

April 2, 2023

Here’s an example:

def func(): pass

def func2(): pass

def test(x):
    if x >0:
        func = func2
    return func


test(0)
UnboundLocalError: cannot access local variable 'func' where it is not associated with a value

In the function test, func is a new variable that gets assigned func2 if x is positive. It shadows the function func defined outside of the test function. So when x=0, the func is treated as a variable which is not defined, and the function func is not called.

func does not fall back to the function func defined outside of the test function.

This is a subtle bug that can be hard to find.

We need to remember that if the same name is used for a variable inside the function, we have to continue to treat it as a variable in the function, even if it’s inside a branched if statement.

To fix this, we can either directly return the function func or func2 in the test function, or we can use a different name for the variable.

def func(): pass

def func2(): pass

def test(x):
    if x >0:
        return func2
    else:
        return func


test(0)
<function __main__.func()>

def func(): pass

def func2(): pass

def test(x):
    if x >0:
        f =  func2
    else:
        f = func
    return f


test(0)
<function __main__.func()>