Skip to content

Improve decorators documentation #91470

Closed
@Booplicate

Description

@Booplicate

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.

Metadata

Metadata

Assignees

Labels

docsDocumentation in the Doc dirtype-featureA feature request or enhancement

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions