Take into account the following code:
def main():
    print('Calling methodA()')
    methodA()
    print('Calling methodB(True)')
    methodB(True)
    print('Calling methodB(False)')
    try:
        methodB(False)
    except UnboundLocalError as error:
        print(f'--> "UnboundLocalError" raised: {error}')
    
def methodA():
    print('Running methodA()')
    print('"method_original" in globals(): ' + str('method_original' in globals()))
    method_original()
def methodB(patch_function):
    print(f'Running methodB({patch_function})')
    print('"method_original" in globals(): ' + str('method_original' in globals()))
    if patch_function:
        method_original=method_patched
    method_original()
def method_original():
    print('Running method_original()')
def method_patched():
    print('Running method_patched()')
    
if __name__ == '__main__':
    main()
It produces the following output:
Calling methodA()
Running methodA()
"method_original" in globals(): True
Running method_original()
Calling methodB(True)
Running methodB(True)
"method_original" in globals(): True
Running method_patched()
Calling methodA(False)
Running methodB(False)
"method_original" in globals(): True
--> "UnboundLocalError" raised: local variable 'method_original' referenced before assignment
Which makes no sense because "method_original" is in globals(). This error can be fixed simply adding global method_original at the beginning of the methodB() but in some cases we have a lot of functions and it could be a pain in the ass to put all of them at the beginning of every method.
Are there any rules to avoid this behavior?
//BR!