I wrote the following toy:
def foo():
x = 5
def foo2():
print("Locals: ", locals())
print("Vars: ", vars())
print("dir: ", dir())
print("CP 1")
print("x =", x)
print("CP 2")
print("Locals: ", locals())
print("Vars: ", vars())
print("dir: ", dir())
foo2()
foo()
print("-----------------------")
def foo():
x = 5
def foo2():
print("Locals: ", locals())
print("Vars: ", vars())
print("dir: ", dir())
print("CP 1")
print("x =", x)
print("CP 2")
del x
print("Locals: ", locals())
print("Vars: ", vars())
print("dir: ", dir())
foo2()
foo()
which produces the following output:
Locals: {'x': 5}
Vars: {'x': 5}
dir: ['x']
CP 1
x = 5
CP 2
Locals: {'x': 5}
Vars: {'x': 5}
dir: ['x']
-----------------------
Locals: {}
Vars: {}
dir: []
CP 1
Traceback (most recent call last):
File "testing.py", line 34, in <module>
foo()
File "testing.py", line 32, in foo
foo2()
File "testing.py", line 26, in foo2
print("x =", x)
UnboundLocalError: local variable 'x' referenced before assignment
>>>
Notice how behaviour of the second edition is modified even in the areas of the code up to which the two editions are identical (and thus should produce identical outcomes). Since x, according to the first edition, does exist in the local namespace, the del statement shouldn't be an issue.
Questions:
1) Is the first or second edition 'right'? Should x exist in the namespace or not?
2) Is there an explanation for this behaviour or is it a bug?
(Follow up to 2: 3) Should the second edition run without an error or is it supposed to crash?)