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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With