Skip to content

Make @cached_property settable? #9726

@tmke8

Description

@tmke8

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions