Python ABC Multiple Inheritance

moeabdol picture moeabdol · Mar 1, 2015 · Viewed 10.5k times · Source

I think the code will explain the problem better than I can do with words. Here is the code in my_abc.py:

from abc import ABCMeta, abstractmethod

class MyABC(object):
    __metaclass__ = ABCMeta

    @abstractmethod
    def print(self):
        pass

Here is the code in my_class.py

from my_abc import MyABC
from third_party_package import SomeClass

class MyClass(MyABC, SomeClass):
    def __init__(self):
        super(MyClass, self).__init__()

    def print(self):
        print('Hello ABC')

When I try to run my_class.py I get:

TypeError: Error when calling the metaclass bases metaclass conflict: the metaclass of a derived class must be a (non-strict) subclass of the metaclasses of all its bases

I understand that I can create a class the inherits directly from my interface MyABC, and then create another class which then inherits from both this class which I created and my third party module class.

My question is: Is there another better and proper way of doing this directly without having to create an intermediate class for my purpose?

Answer

Kevin picture Kevin · Mar 2, 2015

The SomeClass class has a custom metaclass. You will need to create a metaclass which inherits from both ABCMeta and this custom metaclass, then use it as the metaclass for MyClass. Without knowing more about this custom metaclass, I cannot determine a correct way to do this in the general case, but it will probably look like one of these possibilities:

class DerivedMeta(ABCMeta, type(SomeClass)):
    pass

class DerivedMeta(type(SomeClass), ABCMeta):
    pass

It's unlikely but possible you will also need to override one or more methods to ensure correct metaclass interactions.