Description
I'd like to propose a bit more documentation about how @property
works.
In my code example:
import abc
class Base(abc.ABC):
@classmethod
@property
@abc.abstractmethod
def prop1(cls):
return "abc prop 1"
@classmethod
@property
@abc.abstractmethod
def prop2(cls):
return "abc prop 2"
class Test(Base):
prop1 = "prop 1 override"
t = Test()
print(t.prop1, t.prop2)
>>> prop 1 override abc prop 2
Some linters detect the mistake, but Python will let this compile and run. I expect that to crash as prop2
wasn't implemented.
The mistake is the order of @property
and @classmethod
If I correct my base class:
class Base(abc.ABC):
@property
@classmethod
@abc.abstractmethod
def prop1(cls):
return "abc prop 1"
@property
@classmethod
@abc.abstractmethod
def prop2(cls):
return "abc prop 2"
I get the expected TypeError
.
In the docs I found
Class methods can now wrap other descriptors such as property().
But I don't think it can, or at least not in the case of abc. Although, I found no discrepancy in the abc
docs:
When abstractmethod() is applied in combination with other method descriptors, it should be applied as the innermost decorator
Which seems to be consistent with what I got.
It makes total sense we have to apply @property
last! But maybe we could clarify that? Or maybe that @classmethod
shouldn't wrap @property
? Thanks.