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

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