This appears to be a simple misunderstanding about scope in Python. Conditional statements don't create a scope. The name y
is in the local scope inside the function, because of this statement which is present in the syntax tree:
y = 23
This is determined at function definition time, when the function is parsed. The fact that the name y
might be used whilst unbound at runtime is irrelevant.
Here's a simpler example highlighting the same issue:
>>> def foo():
... return y
... y = 23
...
>>> def bar():
... return y
...
>>> foo.func_code.co_varnames
('y',)
>>> bar.func_code.co_varnames
()
>>> foo()
# UnboundLocalError: local variable 'y' referenced before assignment
>>> bar()
# NameError: global name 'y' is not defined