Search code examples
pythonpython-3.xpropertiesabstract-class

How to override an abstract property method without forgetting to add the property decorator in the child class?


I want the Python interpreter to yell at me if I override an abstract property method, but forget to specify that it's still a property method in the child class.

class Parent(metaclass=ABCMeta):
  @property
  @abstractmethod
  def name(self) -> str:
    pass

class Child(Parent):
  @property # If I forget this, I want Python to yell at me.
  def name(self) -> str:
    return 'The Name'

if __name__ == '__main__':
  print(Child().name)

Is there really no built-in way for Python to do this? Must I really create my own decorator to handle this type of behavior?


Solution

  • You could put a runtime check in the Parent's __init__ method, and raise an exception if name is a method.

    class Parent(metaclass=ABCMeta):
      def __init__(self):
        assert not callable(self.name)
    
      @abstractmethod
      def name(self) -> str:
        pass
    
    
    class GoodChild(Parent):
      @property
      def name(self) -> str:
        return 'The Name'
    
    
    class BadChild(Parent):
      def name(self) -> str:
        return 'Whoops, not a property'
    
    
    if __name__ == '__main__':
      good_child = GoodChild()
      print(good_child.name)   # Prints 'The Name'
      bad_child = BadChild()   # Raises an AssertionError when initialized