Guido van Rossum added the comment: Regarding the design of __subclasshook__, these two flaws kind of cancel each other out. The idea is that if you have a "one-trick pony" class whose issubclass() check must verify that the purported sublass implements a specific method (e.g. __hash__), you don't want that subclass check to be inherited by a subclass. I suppose perhaps this ought to have been done by making ABCMeta.__subclasscheck__ check for the __subclasshook__ in the class dict, but (for reasons I've forgotten) it's not doing it that way, instead just calling cls.__subclasscheck__. All known __subclasshook__ implementations (those in collections.abc anyway :-) compensate for this by returning NotImplemented if the class for which they are being called isn't exactly the class in which they are defined. The final piece of the puzzle is object.__subclasshook__(), which always returns NotImplemented.
(NOTE: When reading the above paragraph, be careful to distinguish between __subclasscheck__, which is invoked by issubclass() and isinstance(), and __subclasshook__, which is only invoked by ABCMeta.__subclasscheck__().) Here's an example showing why we don't want __subclasshook__ to be inherited. Suppose we have a class SupportsInt, like this: class SupportsInt(ABC): @classmethod def __subclasshook__(cls, C): return hasattr(C, '__int__') Now suppose we had a concrete class inheriting from this: class MyInteger(SupportsInt): def __int__(self): return 0 Now, alas, everything with an __int__ method is considered to be a MyInteger, for example isinstance(0, MyInteger) returns True. So what should Collection.__subclasshook__ do? It could do something like this: class Collection(Set, Iterable, Container): @classmethod def __subclasshook__(cls, C): if cls is not Collection: return NotImplemented for base in Set, Iterable, Container: ok = base.__subclasshook__(C) if ok != True: return False return True (Untested, hopefully you get the idea. Hope this helps.) ---------- _______________________________________ Python tracker <rep...@bugs.python.org> <http://bugs.python.org/issue27598> _______________________________________ _______________________________________________ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com