How does isinstance work in python for subclasses?

Playing around with isinstance, I would like to know how it works for a subclass check.

class A:

class B(A):

class C(B):

print(isinstance(C(), C)) # True, I understand this fine
print(isinstance(C(), B)) # True, Ok, but how is this `True`?
print(isinstance(C(), A)) # True, this too?

What are the differences between type() and isinstance()? explains that isinstance does work for a subclass as seen in my second and third print statement. My question is not that, but, how does it work? When class A was defined it had no information but about the existence of class B or class C, likewise B had no information about C.

According to How does isinstance work for List? __instancecheck__ is called for isinstance, so if my class A was created before B and C how does this Python know that C() is indeed an instance of one of the subclass (B, subclass of A) or subclass of subclass of A (C, which is a subclass of B which itself is a subclass of A)?

Does something happen when I inherit a class in Python such that the base class knows that a child class exists? If that is the case can anyone let me know how this works?

PS : Do let me know if any clarification is needed. Many Thanks.

Submitted May 02nd 2021 by Admin


The base class doesn't need to know anything about it's inheritance by other classes. When you call the isinstance() on C(), which is a subclass of B (which is a subclass of A) it creates the inheritance tree from C upwards (all the way to object which is the base class of every class). It then "knows" that A and B are there. The order in which you defined A,B,C doesn't have any meaning.

Admin | 4 months ago


C() holds a reference to its type, C, and C has a tuple C.__mro__ of all its ancestors (including itself). The default type.__instancecheck__ looks through that tuple to see whether an object is an instance of a particular class.

If you follow the function calls down from type.__instancecheck__, you eventually end up in this loop:

for (i = 0; i < n; i++) { if (PyTuple_GET_ITEM(mro, i) == (PyObject *)b) return 1;

Classes in Python do also have information about their subclasses - the C-level PyType_Ready function informs the base classes about a subclass while readying the subclass. However, searching the inheritance graph downward from the base class would produce pathologically slow behavior for cases where the second argument to isinstance has a lot of descendants.

Admin | 4 months ago

Relevant Questions

Missing arguement

January 05th 2021