-
-
Notifications
You must be signed in to change notification settings - Fork 2.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Strange error when declaring @final
property
#15325
Comments
So, you want to be able to have separate final properties and their setters? Am I correct? |
Hmm... I wanted to declare the implementation of the settable property final – meaning that subclasses shouldn't be allowed to override the getter or the setter. Do you think this doesn't make sense because EDIT: so, to clarify, I wanted to make getter and setter both final, such that subclassses can override neither, but just making the getter final would also help, I guess |
It will be interesting to make getters final, but allow overwrite setters/getters. Or more generally, to make only a subset of (getter, setter, deleter) final. Usually, overwriting a subset of property accessors in a subclass is done via referencing to superclass property. But this is not currently allowed by mypy: class A:
@property
def a(self) -> int: return 1
class B(A):
@A.a.setter # error: "Callable[[A], int]" has no attribute "setter" [attr-defined]
def a(self, value): pass class A:
@property
def a(self) -> int: return 1
@a.setter
def a(self, value): pass
@a.deleter
def a(self): pass
class B(A):
@A.a.setter # error: overloaded function has no attribute "setter" [attr-defined]
def a(self, value): pass Returning to completely final properties. When a function name is repeated, mypy considers that it is being overloaded. In the example of @tmke8 mypy emits error at I tried to bypass this error via different names for setter and deleter, but ended up with another error: from typing import final
class A:
@property
@final
def a(self) -> int: return 1
@a.setter # error: "Callable[[A], int]" has no attribute "setter" [attr-defined]
def a_setter(self, value): pass
@a_setter.deleter
def a_deleter(self): pass
a = a_deleter
del a_deleter, a_setter
class B(A):
@property # error: Cannot override final attribute "a" (previously declared in base class "A") [misc]
def a(self) -> int: return 2
@a.setter
def a(self, value): pass Then I tried to use from typing import final, Final, reveal_type
class A:
def a_get(self) -> int: return 1
def a_set(self, value): pass
def a_del(self): pass
a: Final[property] = property(a_get, a_set, a_del)
del a_get, a_set, a_del
obj = A()
reveal_type(obj.a) # note: Revealed type is "Any"
a.a = 1 # error: Name "a" is not defined [name-defined]
class B(A):
@property # error: Cannot override final attribute "a" (previously declared in base class "A") [misc]
# error: Signature of "a" incompatible with supertype "A" [override]
def a(self) -> int: return 2
@a.setter
def a(self, value): pass All in all,
Also my examples shows that properties themselves are poorly supported:
|
Bug Report
Consider this code:
https://mypy-play.net/?mypy=latest&python=3.11&gist=a4a1981a3db4ac546b9947bb344a5fd5
Mypy complains that
@final
is not applied to the "overload implementation", but the property is still successfully declared final.I tried moving the
@final
decorator to the setter – in that case, mypy's first error goes away, but then also the second error vanishes, meaning thatx
wasn't actually marked as final.(I also tried moving
@final
above@property
but that produces the same result.)Environment:
See mypy-play link above.
The text was updated successfully, but these errors were encountered: