another super wart

Michele Simionato mis6 at
Wed Mar 12 15:26:39 CET 2003

I have found a very subtle problem (bug?) with super used in conjunction
with __new__. It does not do what I expect.

First of all, let me explain what I expect.

Consider an ancestor class with a new static method

>>> class A(object):
...    def new(): print ''
...    new=staticmethod(new)

and a custom metaclass with a different static method new

>>> class Type(type): 
...    def new(): print ''
...    new=staticmethod(new)

Now derive a base class B from A

>>> class B(A): pass

and a metaclass M from B and Type:
>>> class M(B,Type): pass

Finally, let me create an instance of M with base B:
>>> C=M('C',(B,),{})

Now let me invoke

>>> super(B,C).new() 

This is correct, since the parent of B is A. This means that

>>> super(B,C).new is
>>> super(B,C).new is not

Nevertheless for the __new__ staticmethod I obtain something completely

>>> super(B,C).__new__ is A.__new__
>>> super(B,C).__new__ is not Type.__new__

How is it possible?? It seems that __new__ is very special and behaves
in the opposite way of new! (__init__ instead would work as expected).

Fortunately, there is a workaround, to call super with a C instance:

>>> super(B,C()).__new__ is A.__new__
>>> super(B,C()).__new__ is not Type.__new__

Unfortunately, I cannot use this in my program since super is called inside
__new__, before the instantiation of C. Discovering this very subtle 
inconsistency (which I would call a bug in the implementation of super) 
made me loose an afternoon :-(

Michele Simionato - Dept. of Physics and Astronomy
210 Allen Hall Pittsburgh PA 15260 U.S.A.
Phone: 001-412-624-9041 Fax: 001-412-624-9163

More information about the Python-list mailing list