There is no way to return False
from issubclass when class is derived from class with __subclashook__
implementation. I modified code from:
python subclasscheck & subclasshook
I only added '(Sized)' to both class definitions:
from abc import ABCMeta
class Sized(metaclass=ABCMeta):
@classmethod
def __subclasshook__(cls, C):
if cls is Sized:
if any("__len__" in B.__dict__ for B in C.__mro__):
return True
return NotImplemented
class A(Sized):
pass
class B(Sized):
def __len__(self):
return 0
print(issubclass(A, Sized)) # True - should be False
print(issubclass(B, Sized)) # True
Is there any way to return False
in this case? Or maybe I'm doing something wrong?
The problem is that you return NotImplemented
when the __subclasshook__
doesn't exit early. And as stated in the documentation:
If it returns NotImplemented, the subclass check is continued with the usual mechanism.
So it uses the normal subclass check and finds that you do, in fact, inherit from Sized
so returns True
.
There are two solutions:
return False
instead of return NotImplemented
. However, do you really want/need issubclass
to return False
for direct subclasses?
If you inherit from object
for classes A
and B
it works as expected:
class A(object):
pass
class B(object):
def __len__(self):
return 0
print(issubclass(A, Sized)) # False
print(issubclass(B, Sized)) # True