[Python-Dev] Perverse nesting bug

Tim Peters tim.one@home.com
Sat, 3 Feb 2001 03:17:20 -0500


SF bug reporting is still impossible.

Little program:

def f():
    print "outer f.a is", f.a
    def f():
        print "inner f.a is", f.a
    f.a = 666
    f()
f.a = 42
f()

I'm not sure what I expected it to do, but most likely an UnboundLocalError
(the local f hasn't been bound to yet at the time "print outer" executes).

In reality it prints:

outer f.a is

and then blows up with a null-pointer dereference, here:

		case LOAD_DEREF:
			x = freevars[oparg];
			w = PyCell_Get(x);
			Py_INCREF(w);   /***** THIS IS THE GUY *****/
			PUSH(w);
			break;

Simpler program with same symptom:

def f():
    print "outer f.a is", f.a
    def f():
        print "inner f.a is", f.a
f()

I *do* get an UnboundLocalError if the body of the inner "f" is changed to
"pass":

def f():  # this one works fine!  i.e., UnboundLocalError
    print "outer f.a is", f.a
    def f():
        pass
f()

You'll also be happy to know that this one prints 666 twice (as it should):

def f():
    def f():
        print "inner f.a is", f.a
    f.a = 666
    f()
    print "outer f.a is", f.a
f.a = 42
f()

python-gets-simpler-each-release<wink>-ly y'rs  - tim