Determine if a Python class is an Abstract Base Class or Concrete
Question: My Python application contains many abstract classes and implementations. For
example:

    
    
    import abc
    import datetime
    
    class MessageDisplay(object):
        __metaclass__ = abc.ABCMeta
    
        @abc.abstractproperty
        def display(self, message):
            pass
    
    class FriendlyMessageDisplay(MessageDisplay):
        def greet(self):
            hour = datetime.datetime.now().timetuple().tm_hour
    
            if hour < 7:
                raise Exception("Cannot greet while asleep.")
            elif hour < 12:
                self.display("Good morning!")
            elif hour < 18:
                self.display("Good afternoon!")
            elif hour < 20:
                self.display("Good evening!")
            else:
                self.display("Good night.")
    
    class FriendlyMessagePrinter(FriendlyMessageDisplay):
        def display(self, message):
            print(message)
    

`FriendlyMessagePrinter` is a concrete class that we can use...

    
    
    FriendlyMessagePrinter().greet()
    
    
    
    Good night.
    

...but `MessageDisplay` and `FriendlyMessageDisplay` are abstract classes and
attempting to instantiate one would result in an error:

    
    
    TypeError: Can't instantiate abstract class MessageDisplay with abstract methods say
    

How can I check if a given class object is an (uninstantiatable) abstract
class?


Answer: 
    import inspect
    print(inspect.isabstract(object))                  # False
    print(inspect.isabstract(MessageDisplay))          # True
    print(inspect.isabstract(FriendlyMessageDisplay))  # True
    print(inspect.isabstract(FriendlyMessagePrinter))  # False
    

This checks that the internal flag `TPFLAGS_IS_ABSTRACT` is set in the class
object, so it can't be fooled as easily as your implementation:

    
    
    class Fake:
        __abstractmethods__ = 'bluh'
    
    print(is_abstract(Fake), inspect.isabatract(Fake)) # True, False
    

