Based on my understanding, the second element of int.mro() should have been <class 'type'>, as that is the output of int.__class__. But instead int.mro() gives [<class 'int'>, <class 'object'>]. How is it implemented?
Based on my understanding, the second element of int.mro() should have been <class 'type'>, as that is the output of int.__class__. But instead int.mro() gives [<class 'int'>, <class 'object'>]. How is it implemented?
Looking at the int.mro() shows you the inheritance tree for the int class, not the type metaclass which creates the int class, hence why <class 'type'> shouldn't be in int.mro(). When the metaclass creates the class object, it also builds the __mro__.
Conversely, __class__ is a reference to the type of an instance, showing you the class to which a class instance belongs. In this case, the class to which int belongs is the metaclass type. It is for this reason that x.__class__ is the same as type(x) for the majority of use cases.
You can see the relationship between them in the following examples:
print(int.__class__)
> <class 'type'>
print(int.mro())
> [<class 'int'>, <class 'object'>]
print(int.__class__.__mro__)
> [<class 'type'>, <class 'object'>]
print(int().__class__)
> <class 'int'>
Furthermore, you can see this relationship in the most simple example of a class you can construct:
class A:
pass
obj = A()
print(A.mro())
> [<class '__main__.A'>, <class 'object'>]
print(A.__class__)
> <class 'type'>