When you are inherent in an instance, what you are really doing is a weird way of using a metaclass. Typically, class objects are instances of type . In the case of class B above, it inherits from an instance of Foo . This is exactly what will happen if you define a class with Foo as its metaclass, and then inherit from it.
So, my guess about what is going on here is that Python processes the base classes in reverse MRO order.
Class C works because the first parent class to be processed is Foo , whose class is type . This means that the metaclass D must be type or some subclass. Then Foo() processed, whose class is Foo , which is a subclass of type , so everything is fine.
Class D does not work because the first parent class to be processed is Foo() , which sets the restriction that D has a metaclass from Foo (or a subclass). Then comes Foo , the type class is not a subclass of Foo .
This is a complete hunch, but you can try and see if the Python documentation for metaclasses is required when multiplying inheritance by two classes with different metaclasses, where the metaclasses involved have a subtype relation that you put in a specific order.
source share