filaton
filaton

Reputation: 2326

How are variable assignments detected in a function?

When trying to execute the following code:

a = 1
def test_variable():
    if False:
        a = 2
    print(a)

test_variable()

It fails with UnboundLocalError: local variable 'a' referenced before assignment.

This is in line with how local and global variables work in Python (source, emphasis mine):

variables that are only referenced inside a function are implicitly global. If a variable is assigned a value anywhere within the function’s body, it’s assumed to be a local unless explicitly declared as global.

However, when disassembling the function's code, I get:

  5           0 LOAD_GLOBAL              0 (print)
              2 LOAD_FAST                0 (a)
              4 CALL_FUNCTION            1
              6 POP_TOP
              8 LOAD_CONST               0 (None)
             10 RETURN_VALUE

and we see that there is no trace of a STORE_FAST instruction on the variable a.

Therefore, I'm wondering how does the interpreter know about the variable assignment if it's not present in the bytecode? Or, to phrase it from the opposite point of view: If the interpreter is smart enough to skip the if False block altogether, why doesn't the code execute?

Upvotes: 2

Views: 46

Answers (1)

Barmar
Barmar

Reputation: 780974

The assignment is detected by the parser, not by the byte-code interpreter. Since it sees an assignment somewhere in the function, it treats a as a local variable. The LOAD_FAST instruction accesses local variables, and it gets an error because the variable doesn't exist.

Add a global a statement and compare the resulting disassembly. I think LOAD_FAST will be changed to LOAD_GLOBAL.

Upvotes: 1

Related Questions