I found a weird behavior with cpython 2.5, 2.7, 3.2 and pypy with metaclass that override __new__
when using the python 2 / python 3 compatible way of using metaclass :
Given a module m1:
class C1Meta(type):
def __new__(cls, name, bases, dct):
return type.__new__(cls, name, bases, dct)
C1 = C1Meta('C1', (object,), {})
class C2Meta(type):
pass
C2 = C2Meta('C2', (object,), {})
And the following main program:
import m1
C10 = m1.C1Meta('C10', (m1.C1,), {})
class C11Meta(m1.C1Meta):
pass
C11 = C11Meta('C11', (m1.C1,), {})
class C12Meta(m1.C1Meta):
def __new__(cls, name, bases, dct):
return m1.C1Meta.__new__(cls, name, bases, dct)
C12 = C12Meta('C12', (m1.C1,), {})
class C13Meta(m1.C1Meta):
def __new__(cls, name, bases, dct):
return type.__new__(cls, name, bases, dct)
C13 = C13Meta('C13', (m1.C1,), {})
C20 = m1.C2Meta('C20', (m1.C2,), {})
class C21Meta(m1.C2Meta):
pass
C21 = C21Meta('C21', (m1.C2,), {})
class C22Meta(m1.C2Meta):
def __new__(cls, name, bases, dct):
return m1.C2Meta.__new__(cls, name, bases, dct)
C22 = C22Meta('C22', (m1.C2,), {})
class C23Meta(m1.C2Meta):
def __new__(cls, name, bases, dct):
return type.__new__(cls, name, bases, dct)
C23 = C23Meta('C23', (m1.C2,), {})
print(C10)
print(C11)
print(C12)
print(C13)
print(C20)
print(C21)
print(C22)
print(C23)
Running the script will produce the following output (with all the mentioned python versions) :
<class 'm1.C10'>
<class 'm1.C11'>
<class 'm1.C12'>
<class '__main__.C13'>
<class '__main__.C20'>
<class '__main__.C21'>
<class '__main__.C22'>
<class '__main__.C23'>
-> the C10, C11 and C12 classes module is wrong !
Is it an expected behavior ?
Is there a way to override new that will not raise the issue ?
Thanks,
Christophe