[Python-Dev] python and super

Michael Foord fuzzyman at voidspace.org.uk
Fri Apr 15 15:53:26 CEST 2011


On 15/04/2011 02:23, Steven D'Aprano wrote:
> Ricardo Kirkner wrote:
>
>> I have a TestCase class, which inherits from both Django's TestCase
>> and from some custom TestCases that act as mixin classes. So I have
>> something like
>>
>> class MyTestCase(TestCase, Mixin1, Mixin2):
>>    ...
>>
>> now django's TestCase class inherits from unittest2.TestCase, which we
>> found was not calling super. Even if this is a bug and should be fixed
>> in unittest2, this is an example where I, as a consumer of django,
>> shouldn't have to be worried about how django's TestCase class is
>> implemented. Since I explicitely base off 3 classes, I expected all 3
>> classes to be initialized, and I expect the setUp method to be called
>> on all of them.
>>
>> If I'm assuming/expecting unreasonable things, please enlighten me.
>
> If we treat django's failure to use super as a bug, you want the 
> Python language to work-around that bug so that:

What you say (that this particular circumstance could be treated as a 
bug in django) is true, however consider the "recently" introduced 
problem caused by object.__init__ not taking arguments. This makes it 
impossible to use super correctly in various circumstances.

     http://freshfoo.com/blog/object__init__takes_no_parameters

Given the following classes (Python 3):

class A:
     def __init__(self, a):
         print ('A')

class B:
     def __init__(self, a):
         print ('B')

class C(B):
     def __init__(self, a):
         print ('C')
         super().__init__(a)

It is impossible to inherit from both C and A and have all parent 
__init__ methods called correctly. Changing the semantics of super as 
described would fix this problem.

For:

class D(C, A):
     def __init__(self, a):
         super().__init__(a)

D(1)

This is printed:
C
B

(A __init__ is not called).

For this:

class D(A, C):
     def __init__(self, a):
         super().__init__(a)

D(1)

The following is printed:
A

(B and C __init__ methods are not called.)

All the best,

Michael Foord


>
> "I, as a consumer of django, shouldn't have to be worried about bugs 
> in django". (For at least one class of bug.)
>
> If we *don't* treat django's failure to use super as a bug, but as a 
> deliberate design choice, then you are trying to do something which 
> django doesn't support. Possibly *deliberately* doesn't support. You 
> want the Python language to add that support so that:
>
> "I, as a consumer of django, shouldn't have to be worried about 
> whether django supports what I want to do or not".
>
> Either way you look at it, I think it's extremely unreasonable to 
> expect the language to work-around bugs in third-party applications, 
> or to add features to them that the third-party developers either 
> didn't consider or don't want.
>
> Multiple inheritance is tricky enough to get right without adding "Do 
> What I Mean" black magic to it. I'd rather work around bugs in 
> third-party classes than try to deal with Python actively subverting 
> the code I read and write by mysteriously calling superclass methods 
> where there is no call to a superclass method.
>
>
>
>


-- 
http://www.voidspace.org.uk/

May you do good and not evil
May you find forgiveness for yourself and forgive others
May you share freely, never taking more than you give.
-- the sqlite blessing http://www.sqlite.org/different.html



More information about the Python-Dev mailing list