Issue 33417: Isinstance() behavior is not consistent with the document (original) (raw)

In the PEP 3119(https://www.python.org/dev/peps/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):
    pass

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):
    pass

class B(object):
    pass

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.