Proposal: allow chaining @final decorator when previous decorators return a non-function

Currently, the typing spec for @final (link) states:

It is an error to use `@final` on a non-method function.

I think this restriction makes sense, as we have capital-F Final for attributes, including property descriptors.

I propose that we also allow the @final decorator to be applied on top of decorators that return non-functions. For example, a decorator that returns a descriptor, like @property:

from typing import final

class Base:
    @final
    @property
    def p(self) -> int:
        return 0

class Derived(Base):
    @property
    def p(self) -> bool: # Expected error: p can not be overridden
        return True

For these cases, it’s not possible to use the Final annotation, since there’s nowhere to put that annotation.

1 Like

I may have read/written too hastily. I see that the spec also clearly states:

The method decorator version may be used with all of instance methods, class methods, static methods, and properties.

And indeed Mypy already implements the behavior I am proposing for chained decorators. If it’s agreeable, I am happy to do (a) add additional language, an example to the spec and (b) add a conformance test.

Yes, I think it was always intended to allow final properties. Feel free to send a PR clarifying the text and adding a test for this behavior.

1 Like

It could also be interpreted as that you should the @final on the method itself, instead of the property, so like:

class Base:
    @property
    @final
    def p(self) -> int:
        return 0