[MERGE] test framework distinguishes skips

Martin Pool mbp at canonical.com
Sun Jul 9 02:05:12 BST 2006


On 09/07/2006, at 3:59 AM, Aaron Bentley wrote:

> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA1
>
> Andrew Bennetts wrote:
>> On Fri, Jul 07, 2006 at 01:50:53PM -0500, John Arbash Meinel wrote:
>>
>> super is only really safe if *all* base classes use it.  It's main  
>> advantage is
>> that it handles complex multiple inheritance trees nicely (e.g.  
>> ones with
>> diamonds in them), but it cannot reliably do that unless all the  
>> base classes
>> also use super.  bzrlib.tests.TestCase uses super, but its parent
>> (unittest.TestCase) doesn't, so it's not wholly safe for TestCase  
>> either.
>>
>> http://fuhm.net/super-harmful/ explains the subtleties and  
>> pitfalls of super
>> fairly well.

Yes, that is an interesting link.  We're not complying with the rules  
in there at the moment; in particular I think many classes that  
inherit from object do not call super().  They would need to do so to  
be safely multiply-inherited - but then those classes are not  
designed for MI anyhow.  So for the majority of our code it's  
probably better to just not use it.

> Thanks for the link.  I'm somewhat baffled about super.

I think it's quite a wart on Python.

> My impression is that its intended purpose is to cause its caller to
> call a same-name method on an unrelated class.  (Unrelated from the
> perspective of the class itself, but having a common subclass.)

The purpose is to make sure that all the virtual-superclass methods  
get called in a deterministic order.  The *effect* is that in the  
presence of multiple inheritance, super() will call something which  
is not a superclass of the class in which the call occurred, but  
rather another superclass of the dynamic type of self.

> Unless one controls all the classes, it seems hard to predict  
> whether the two
> methods will interact in unfortunate ways.

In general: it's not likely to be easy to inherit from multiple bases  
unless one or both of them were designed to be used this way.  I'd go  
further and say that in most cases it's not easy to change a class by  
inheriting from it, unless that class already considered extension in  
this way.

> When subclassing, I find I'm often faced with the decision of  
> whether to
> supplement the base class method or override it.  Using super seems to
> make that decision almost impossible.  What if the called method  
> throws
> NotImplemented?

Part of the class's contract is whether and how it can be subclassed  
or extended.

There are some patterns:

  - replace the method entirely
  - call the super implementation first, then do your own thing  
(common for constructors/initializers where you need to set some more  
fields)
  - do something else before and after calling the super method
  - do your own thing and don't call the super method

There's also an inverted control pattern where the subclass will  
provide the "real" implementation, but the superclass needs control  
of it.  So here we tend to have a protected method which is only  
called by the superclass, and the method that calls it should not be  
overridden.

Sometimes that's not explicitly documented but can be seen from the  
code - e.g. the Transport base methods which say "not implemented on  
this transport" are a big clue that you can/should implement them if  
you can.

To sum up: the base class should tell you what to do and if it does  
not, it's a bug.

> Additionally, since it's possible that the method called by super will
> have different parameters, it seems like self, *args and **kwargs are
> the only safe parameters for a method that invokes super, and using
> those exclusively seems like a great loss.

In our code we should always know which method will actually end up  
being called, and so what parameters it will take.  Then the choice of

   super(SomeSubclass, self).method()

vs

   SuperClass.method(self)

just comes down to relative clarity, vs not repeating the superclass  
name.   I used to prefer the first for this reason but now I'm not so  
sure.

-- 
Martin







More information about the bazaar mailing list