Title: Isinstance() behavior is not consistent with the document
Type: behavior Stage: resolved
Components: Documentation, Interpreter Core Versions: Python 3.8, Python 3.7
Status: closed Resolution: not a bug
Dependencies: Superseder:
Assigned To: docs@python Nosy List: docs@python, hongweipeng, terry.reedy
Priority: normal Keywords:

Created on 2018-05-03 10:30 by hongweipeng, last changed 2018-05-04 21:42 by terry.reedy. This issue is now closed.

Messages (2)
msg316118 - (view) Author: hongweipeng (hongweipeng) * Date: 2018-05-03 10:30
In the PEP 3119(,it introduce about Customizing instance and subclass checks.

>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.

but my code doesn't works.
class Sizeable(object):
    def __instancecheck__(cls, instance):
        print("__instancecheck__ call")
        return hasattr(instance, "__len__")

class B(object):

b = B()
print(isinstance(b, Sizeable)) # output:False
The __instancecheck__ function  is not called. In PyObject_IsInstance,when isinstance(x, C) the following three conditions are reached, __instancecheck__ will take effect:
1. x can not be directly instantiated by C;

2. The C class specifies the metaclass;

3. The __instancecheck__ in the specified metaclass class is defined.

This code can work:
class MetaSizeable(type):
    def __instancecheck__(cls, instance):
        print("__instancecheck__ call")
        return hasattr(instance, "__len__")

class Sizeable(metaclass=MetaSizeable):

class B(object):

b = B()
print(isinstance(b, Sizeable))  # output: False
print(isinstance([], Sizeable)) # output: True

So,the problem is that the document does not conform to the reality.Can it be guaranteed that __instancecheck__  is always called?

If yes: PyObject_IsInstance should be tweaked.
If no:  document should be tweaked.
msg316186 - (view) Author: Terry J. Reedy (terry.reedy) * (Python committer) Date: 2018-05-04 21:42
"Note that these methods are looked up on the type (metaclass) of a class. They cannot be defined as class methods in the actual class. This is consistent with the lookup of special methods that are called on instances, only in this case the instance is itself a class."

IE, your first example is documented as wrong.  Your second example, which works, follows the example in
Date User Action Args
2018-05-04 21:42:38terry.reedysetstatus: open -> closed

versions: + Python 3.8
nosy: + terry.reedy

messages: + msg316186
resolution: not a bug
stage: resolved
2018-05-03 10:30:05hongweipengcreate