The documentation notes:
The mechanics of cached_property() are somewhat different from property(). A regular property blocks attribute writes unless a setter is defined. In contrast, a cached_property allows writes.
And mypy has @cached_property special-cased to be settable: https://github.com/python/mypy/blob/ad82257170636871a0062ebe6fb82fb45523f580/mypy/semanal.py#L1508-L1509 So, mypy allows assignments to the property even though __set__ isn't defined in typeshed.
But in pyright it isn't settable, because pyright just follows typeshed. I raised an issue about it: microsoft/pyright#4438 but pyright (somewhat understandably) doesn't want to special-case @cached_property.
So, my proposal is now to add __set__ method to the typestub of @cached_property. Something like this:
class cached_property(Generic[_T]):
# [...]
def __set__(self, instance: object, value: _T) -> None: ...
I have confirmed that at runtime, overwriting a cached property seems to work at any time, even if it hasn't been called yet:
>>> from functools import cached_property
>>> class A:
... @cached_property
... def c(self):
... return 0
...
>>> a = A()
>>> a.c = 3
>>> a.c
3
>>> a = A()
>>> a.c
0
>>> a.c = 2
>>> a.c
2
The documentation notes:
And mypy has
@cached_propertyspecial-cased to be settable: https://github.com/python/mypy/blob/ad82257170636871a0062ebe6fb82fb45523f580/mypy/semanal.py#L1508-L1509 So, mypy allows assignments to the property even though__set__isn't defined in typeshed.But in pyright it isn't settable, because pyright just follows typeshed. I raised an issue about it: microsoft/pyright#4438 but pyright (somewhat understandably) doesn't want to special-case
@cached_property.So, my proposal is now to add
__set__method to the typestub of@cached_property. Something like this:I have confirmed that at runtime, overwriting a cached property seems to work at any time, even if it hasn't been called yet: