Why does using property and abstractmethod not enforce properties in child?

Example:

from abc import ABC, abstractmethod

class AbstractExample(ABC):
    @property
    @abstractmethod
    def some_prop(self):
        pass

class ConcreteExample(AbstractExample):
    def some_prop(self):
        return None

c = ConcreteExample() # this does not raise

Why should it raise? You have done exactly what an abstract method is for - you implemented some_prop in in a child class.

When some_prop is searched for in a ConcreteExample instance, it will look in the instance, after that in the class, where it finds a usable entry. Because it is not decorated as a property, it is a normal method.

1 Like

I understand why it does not raise, but it doesn’t make sense. The documentation for abstractproperty hints that this what was intended. I emphasis: ‘…as the property decorator is now correctly identified as abstract when applied to an abstract method’

Yet the example given in that doc suffers from the same issue. Simply copy-paste the last two codeblocks, but remove ‘@C.x.setter’ line in the latter, D still instantiates fine.

from abc import abstractmethod, ABC

class C(ABC):
    @property
    def x(self):  ...

    @x.setter
    @abstractmethod
    def x(self, val): ...


class D(C):
    def x(self, val):  ...


d = D()

By deleting the decorator you changed the property setter in D to an ordinary method, shadowing the property x. From D the property is no longer reachable. So the quoted part of the answer applies when you change some_prop to x and ConcreteExample to D.

@SuaveSteve If you are still interested in a quick solution see my answer Here