[Python-3000] Updated and simplified PEP 3141: A Type Hierarchy for Numbers (original) (raw)

Collin Winter collinw at gmail.com
Thu May 17 18:37:39 CEST 2007


On 5/17/07, Nick Coghlan <ncoghlan at gmail.com> wrote:

Talin wrote: > This really highlights what I think is a problem with dynamic > inheritance, and I think that this inconsistency between traditional and > dynamic inheritance will eventually come back to haunt us. It has always > been the case in the past that for every property of class B, if > isinstance(A, B) == True, then A also has that property, either > inherited from B, or overridden in A. The fact that this invariant will > no longer hold true is a problem in my opinion. > > I realize that there isn't currently a solution to efficiently allow > inheritance of properties via dynamic inheritance. As a software > engineer, however, I generally feel that if a feature is unreliable, > then it shouldn't be used at all. So if I were designing a class > hierarchy of ABCs, I would probably make a rule for myself not to define > any properties or methods in the ABCs at all, and to only use ABCs for > type testing via 'isinstance'.

If a class doesn't implement the interface defined by an ABC, you should NOT be registering it with that ABC via dynamic inheritance. That's the bug - the program is claiming that "instances of class A can be treated as if they were an instance of B" when that statement is simply not true. And without defining an interface, dispatching on the ABC is pointless - you don't know whether or not you support the operations implied by that ABC because there aren't any defined!

ABCs can define concrete methods. These concrete methods provide functionality that the child classes do not themselves provide. Let's imagine that Python didn't have the readlines() method, and that I wanted to define one. I could create an ABC that provides a default concrete implementation of readlines() in terms of readline().

class ReadlinesABC(metaclass=ABCMeta): def readlines(self): # some concrete implementation

@abstractmethod def readline(self): pass

If I register a Python-language class as implementing this ABC, "isinstance(x, ReadlinesABC) == True" means that I can now call the readlines() method. However, if I register a C-language extension class as implementing this ABC, "isinstance(x, ReadlinesABC) == True" may or may not indicate that I can call readlines(), making the test of questionable value.

You can say that I shouldn't have registered a C extension class with this ABC in the first place, but that's not the point. The point is that for consumer code "isinstance(x, ReadlinesABC) == True" is an unreliable test that may or may not accurately reflect the object's true capabilities.

Maybe attempting to use partially-concrete ABCs in tandem with C classes should raise an exception. That would make this whole issue go away.

Collin Winter



More information about the Python-3000 mailing list