I think that the PEP describing __instancecheck__()
is faulty. PEP 3119 says:
The primary mechanism proposed here is to allow overloading the
built-in functions isinstance() and issubclass(). The overloading
works as follows: The call isinstance(x, C) first checks whether
C.__instancecheck__
exists, and if so, calls C.__instancecheck__(x)
instead of its normal implementation.
You can write:
class C:
def do_stuff(self):
print('hello')
C.do_stuff(C())
So based on the quote above from the PEP, you should be able to write
class C:
@classmethod
def __instancecheck__(cls, x):
print('hello')
C.__instancecheck__(C())
--output:--
hello
But isinstance() does not call that method:
class C:
@classmethod
def __instancecheck__(cls, y):
print('hello')
x = C()
isinstance(x, C)
--output:--
<nothing>
The PEP then goes on to say:
These methods are intended to be be called on classes whose metaclass
is (derived from) ABCMeta...
Okay, let's try that:
import abc
class MyMeta(abc.ABCMeta): #A metaclass derived from ABCMeta
def __instancecheck__(cls, inst):
print('hello')
return True
class C(metaclass=MyMeta): #A class whose metaclass is derived from ABCMeta
pass
x = C()
C.__instancecheck__(x)
--output:--
hello
But once again isinstance() does not call that method:
isinstance(x, C)
--output:--
<nothing>
Conclusion: PEP 3119 needs to be rewritten--along with the "Data Model" docs.