It is not a problem to mix old and new style classes. The super () function does not call all the functions of the base classes, it calls the first one found in accordance with the order of resolution of the method. In this case, A2, which in turn calls A.
If you want to call both, do it explicitly:
class C(A2, B2): def __init__(self): A2.__init__(self) B2.__init__(self) print 'class C'
This should solve the problem.
Update:
The problem of diamond inheritance that you refer to is the question of what class should be called in the situation of diamond inheritance, for example:
class A: def method1(self): print 'class A' def method2(self): print 'class A' class B(A): def method1(self): print 'class B' class C(A): def method1(self): print 'class C' def method2(self): print 'class C' class D(B, C): pass
Now check this out:
>>> D().method1() 'class B'
It is right. It calls the implementation of the first class. However, try this with method2:
>>> D().method2() 'class A'
Smiles, WRONG! He should have called class C.method2 () here, because although class B does not override method2, class C does. Now make class A a class newstyle:
class A(object): def method1(self): print 'class A'
And try again:
>>> D().method1() 'class B' >>> D().method2() 'class C'
and hey presto, it works. This is the difference between the method resolution orders between the new and old style classes, and this is what sometimes makes them mix.
Notice that calls B and C are by no means called. This is true even if we call super.
class D(B, C): def method1(self): super(D, self).method1() def method2(self): super(D, self).method2() >>> D().method1() 'class B' >>> D().method2() 'class C'
If you want to call both B and C, you MUST call both explicitly.
Now, if you unlock the diamond, as in your example with separate base classes, the result will be different:
class A1(object): def method1(self): print 'class A1' def method2(self): print 'class A1' class A2(object): def method1(self): print 'class A2' def method2(self): print 'class A2' class B(A1): def method1(self): print 'class B' class C(A2): def method1(self): print 'class C' def method2(self): print 'class C' class D(B, C): def method1(self): super(D, self).method1() def method2(self): super(D, self).method2() >>> D().method1() 'class B' >>> D().method2() 'class A1'
It is also for design. Nowhere else are two base classes called. If you want this to happen, you still need to call both explicitly.