Scoping "bug" ?

Kevin Bailey noone at nowhere.com
Fri Aug 18 11:06:47 EDT 2000


I get the feeling that this isn't a bug but I'd be quite disappointed
if this is intended behavior:

Python 1.5.2 (#2, Jun  9 2000, 16:02:51)  [GCC 2.95.2 19991024 (release)]
Copyright 1991-1995 Stichting Mathematisch Centrum, Amsterdam
>>> a = 1
>>> def fun1(x):
...     if x:
...             print a
... 
>>> def fun2(x):
...     if x:
...             print a
...     else:
...             a = 2
... 
>>> fun1(1)
1
>>> fun2(1)
Traceback (innermost last):
  File "<stdin>", line 1, in ?
  File "<stdin>", line 3, in fun2
NameError: a
>>> 

In case it's not obvious, the exact same code 'if x: print a' does
different things in these functions simply because of the presence of
some _later_ code which may _never_ execute (and certainly _doesn't_
execute whenever 'print a' does.) This is completely non-intuitive
behavior. It is as though 'a' gets "half-way" defined in function 'fun2'.
It gets defined enough for a reference to it to match locally
before matching globally yet it doesn't get defined enough to avoid the
NameError. We have a new level of variable definition now ? Something
akin to Shreodinger's cat ?

Best case is that this is intended to avoid errors. That is, if the
interpretter executes the 'print a' code, you'll discover a scoping
problem. This is insufficient, however, because if the 'a = 2'
code only ever executes, you have bug and you'd be hard pressed to
find it.

But what's really wrong is that Python has unexpected scoping rules
when it doesn't need to have them. I thought the whole point of
Python was to be able to teach programming without having to stop
and teach a lot of exceptions. Instead of:

if the variable is defined locally, use it else
if the variable is defined in the module, use it else
...

its now:

if the variable is defined locally, use it unless
the variable "may" be defined locally in which case behave
in a totally strange manner unlike any other language ...

If the goal here is to avoid errors, the interpretter should spit
out a warning instead of perverting the scoping rules. Something
like 'global variable used in same function as it is defined locally'
should raise eyebrows.

Someone please tell me this is just a bug.



More information about the Python-list mailing list