Why does this simple change introduce "'global_variable' is assigned to before global declaration" SyntaxError?

Question:

I am fairly new to Python and would be very thankful for any explanation on this:

I have a question about how and why the compiler behaves strangely (in my opinion) in case of declaring global variables using keyword global in different scopes

When I run this piece of code it works perfectly fine:

global_variable = 0


def change_global(condition):
    global global_variable
    if condition:
        global_variable = 1
    else:
        global_variable = 2


if __name__ == '__main__':
    print(global_variable)
    change_global(True)
    print(global_variable)
    change_global(False)
    print(global_variable)

Output:
0
1
2

Process finished with exit code 0

But if I do the same but split the declaration for each case of condition value:

global_variable = 0


def change_global(condition):
    if condition:
        global global_variable
        global_variable = 1
    else:
        global global_variable
        global_variable = 2


if __name__ == '__main__':
    print(global_variable)
    change_global(True)
    print(global_variable)
    change_global(False)
    print(global_variable)

I get the

global global_variable
^^^^^^^^^^^^^^^^^^^^^^ SyntaxError: name 'global_variable' is assigned to before global declaration

Is it caused by compiler preemptively trying to avoid errors?

Because, as I understand, during the execution there will never be any problem like declaring global_variable as global twice

Or am I missing something here?

Edit:

This works fine as well, even though I changed the order of conditions meeting and declared variable as global only in the first one

global_variable = 0


def change_global(condition):
    if condition:
        global global_variable
        global_variable = 1
    else:
        global_variable = 2



if __name__ == '__main__':
    print(global_variable)
    change_global(False)
    print(global_variable)
    change_global(True)
    print(global_variable)

Output:
0
2
1

Process finished with exit code 0
Asked By: Tim Korelov

||

Answers:

From the documentation:

Names listed in a global statement must not be used in the same code block textually preceding that global statement.

You have a global global_variable statement in the else: block. You use the variable in the if block, which precedes that declaration. The fact that there’s another global declaration for the same variable before this doesn’t matter, each one is checked independently. You can see the same thing more simply with:

def change_global():
    global foo
    foo = 1
    global foo

This will report the same syntax error.

Putting the declaration in the if or else block doesn’t restrict its interpretation. global declarations don’t have to be executed, they’re processed at compile time and apply to the entire function definition.

Answered By: Barmar