I have a class that inherits from ABC
, and does not have any abstractmethod
.
I would like to check if it's an abstract class, and am currently stumped.
Determine if a Python class is an Abstract Base Class or Concrete prescribes using inspect.isabstract
. However, this only works if an abstractmethod
has been used.
How can I detect if a class inherits directly from ABC
, without using inspect.isabstract
?
Test Cases
# I need this to be flagged as abstract
class AbstractBaseClassNoAbsMethod(ABC):
pass
# This is currently flaggable with `inspect.isabstract`
class AbstractBaseClassWithAbsMethod(ABC):
@abstractmethod
def some_method(self):
"""Abstract method."""
# I need this to be flagged as not abstract
class ChildClassFromNoAbsMethod(AbstractBaseClassNoAbsMethod):
pass
I considered using issubclass(some_class, ABC)
, but this is True
, even for the above ChildClassFromNoAbsMethod
.
Current Best Solution
My current best solution works using __bases__
. This is basically just listing parent classes, see How to get the parents of a Python class?
def my_isabstract(obj) -> bool:
"""Get if ABC is in the object's __bases__ attribute."""
try:
return ABC in obj.__bases__
except AttributeError:
return False
This is a viable solution. I am not sure if there is a better/more standard way out there.
AbstractBaseClassNoAbsMethod
isn't abstract. Inheriting from ABC
doesn't make a class abstract. inspect.isabstract
is producing correct results. You'll also see that no error occurs if you try to instantiate AbstractBaseClassNoAbsMethod
, while attempting to instantiate an actually abstract class raises an exception.
If you want to test whether a class inherits directly from abc.ABC
, you can do what you're already doing with __bases__
, but many abstract classes don't inherit from abc.ABC
. For example, this is an abstract class:
class Abstract(metaclass=abc.ABCMeta):
@abc.abstractmethod
def foo(self):
pass
and so is B
in this example:
class A(abc.ABC):
@abc.abstractmethod
def foo(self):
pass
class B(A): pass
but neither Abstract
nor B
inherits directly from abc.ABC
.