On 4/29/07, Guido van Rossum
Hmm... Maybe the conclusion to draw from this is that we shouldn't make Ring a class? Maybe it ought to be a metaclass, so we could ask isinstance(Complex, Ring)?
Yes; all the ABCs are assertions about the class. (Zope interfaces do support instance-specific interfaces, which has been brought up as a relative weakness of ABCs.) The only thing two subclasses of an *Abstract* class need to have in common is that they both (independently) meet the requirements of the ABC. If not for complexity of implementation, that would be better described as a common metaclass. Using a metaclass would also solve the "when to gripe" issue; the metaclass would gripe if it couldn't make every method concrete. If this just used the standard metaclass machinery, then it would mean a much deeper metaclass hierarchy than we're used to; MutableSet would a have highly dervived metaclass.
The more I think about it, it sounds like the right thing to do. To take PartiallyOrdered (let's say PO for brevity) as an example, the Set class should specify PO as a metaclass. The PO metaclass could require that the class implement __lt__ and __le__. If it found a class that didn't implement them, it could make the class abstract by adding the missing methods to its __abstractmethods__ attribute.
Or by making it a sub(meta)class, instead of a (regular instance) class.
if it found that the class implemented one but not the other, it could inject a default implementation of the other in terms of the one and __eq__.
This also allows greater freedom in specifying which subsets of methods must be defined.
Now, you could argue that Complex should also be a metaclass. While that may mathematically meaningful (for all I know there are people doing complex number theory using Complex[Z/n]), for Python's numeric classes I think it's better to make Complex a regular class representing all the usual complex numbers (i.e. a pair of Real numbers).
complex already meets that need. Complex would be the metaclass representing the restrictions on the class, so that independing implementations wouldn't have to fake-inherit from complex.
I expect that the complex subclasses used in practice are all happy under mixed arithmetic using the usual definition of mixed arithmetic: convert both arguments to a common base class and compute the operation in that domain.
It is reasonable to insist that all Complex classes have a way to tranform their instances into (builtin) complex instances, if only as a final fallback. There is no need for complex to be a base class. -jJ