Metaclass conflict, multiple inheritance, and instance as parent

I was fiddling with the dark arts of Python and there is something that I would like to help understand. Given the Foo class, here are some of the ways I tried to inherit from it:

  • class A(Foo) - Works, no wonder.
  • class B(Foo()) - submitted work Foo has the corresponding __new__ method (which I provided)
  • class C(Foo(), Foo) - works on the same conditions as B
  • class D(Foo, Foo()) - gives a known metaclass error:

    Traceback (last last call):
    File "test.py", line 59, in
    class n (Foo, Foo ()):
    TypeError: metaclass conflict: the metaclass of the derived class must be a (non-strict) subclass of the metaclasses of all its bases

What exactly is causing this conflict? When I inherit from (Foo(), Foo) (instance first, second class), it works, but when I inherit from (Foo, Foo()) (class first, second instance), it doesn't.

+4
source share
1 answer

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.

+5
source

All Articles