another super wart
Michele Simionato
mis6 at pitt.edu
Wed Mar 12 09:26:39 EST 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 'A.new'
... new=staticmethod(new)
and a custom metaclass with a different static method new
>>> class Type(type):
... def new(): print 'Type.new'
... 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()
A.new
This is correct, since the parent of B is A. This means that
>>> super(B,C).new is A.new
True
>>> super(B,C).new is not Type.new
True
Nevertheless for the __new__ staticmethod I obtain something completely
different!!
>>> super(B,C).__new__ is A.__new__
False
>>> super(B,C).__new__ is not Type.__new__
False
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__
True
>>> super(B,C()).__new__ is not Type.__new__
True
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
Home-page: http://www.phyast.pitt.edu/~micheles/
More information about the Python-list
mailing list