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.
Answer from Kevin on Stack OverflowThe 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.
Thread is still at the top in search result, so I wanted to share my complete solution.
I ran into this problem when trying to create an abstract template class meant to PyQt5 widgets, in Python 3.8. I applied @Kevin's solution, creating a new meta class first. The working code:
from abc import ABC, ABCMeta
from PyQt5.QtWidgets import QWidget, QLabel
class QABCMeta(ABCMeta, type(QWidget)):
"""Create a meta class that combines ABC and the Qt meta class"""
pass
class TcWidget(ABC, metaclass=QABCMeta):
"""Abstract class, to be multi-inherited together with a Qt item"""
pass
class TcLabel(QLabel, TcWidget):
"""Label that shows a value"""
pass
# ...
label = TcLabel()
# ...
There's no technical need to re-inherit ABC, but some linters may complain and people may argue that a class with abstract methods should explicitly inherit ABC to make the intention clear that the class is still abstract, and not a mistake. This especially goes for cases like this, where you don't explicitly declare any obvious abstract methods:
class C(Base):
def m(self):
...
Did you just miss implementing foo here, or did you intent to keep C an abstract class? Make it explicit by inheriting ABC.
WithAbstract inherits from Base which already inherits from abc.ABC so you don't have to inherit from abc.ABC again.
Unless all of a sudden Base ceases to inherit from abc.ABC and your code breaks.
I don't know about pythonic but I would tend to avoid multiple inheritance. True, it's not as problematic as in other languages like C++ but simple is better than complex.
If all the descendants of Base have to use @abc.abstractmethod decorator, then it's better to make it available from Base to avoid unnecessary copy/paste when creating a new child class.