Luciano Ramalho <luciano@ramalho.org> added the comment:
FYI, the usual term is "data descriptor" instead of "overriding descriptor".
Yes, the Python docs are consistent in always using "data descriptor", but I've adopted "overriding descriptor" from Martelli's Python in a Nutshell--in Fluent Python I also put a note saying that "data descriptor" is used in the docs. I think "overriding descriptor" is more descriptive. In particular, I find "non-data descriptor" quite puzzling. But this issue is not about changing the jargon.
Normally the docs for things like property() and cached_property() don't mention the term descriptor at all. From the user point of view, that is an implementation detail.
I'd agree, if I wasn't personally bitten by the issue I reported. I was refactoring an existing class which had hand-made caches in a couple of methods decorated with @property. When I discovered @cached_property, I tried to simplify my code by using it, and it broke my code in one place, but not in the other. Leonardo Rochael had experience with cached_property and told me about the difference. I suggest a warning noting the different behavior regarding existing instance attributes. The warning doesn't need to assume the user knows what is a descriptor, but it should in my opinion point to your excellent Descriptor HowTo Guide for more information.
I would suggest a small amendment, and say "cached as a normal attribute with the same name". The choice of attribute isn't arbitrary, it is exactly the same as the cached property.
That's good too.
In the future, perhaps we can add an argument to @cached_property to optionally make it produce overriding descriptors.
That doesn't make any sense to me. It would defeat the entire mechanism for cached_property().
My idea would be to add a dummy __set__ method if the overriding option was True (default would be False). The method could raise an exception. But its presence would make @cached_property behave more like @property in the most common use case of @property: as an overriding descriptor emulating a read-only attribute.
If a user replaces a @property with a @cached_property, her code may or may not break depending on the existence of an instance attribute with the same name as the decorated method.
We've never had a report of an issue like this and I don't expect to see over.
You just did ;-). I filed this issue after spending hours trying to figure out what the problem was in my code on my second attempt at using @cached_property. I expected @cached_property would work as a drop-in replacement for @property when emulating a read-only attribute, and it did not.
One other possible addition is to note that the attribute is writeable:
Yes, the code snippet you suggested is a good way of saying "this produces a non-overriding descriptor". However we want to say it, I think it is important to contrast the behavior of @cached_property v. @property regarding the presence of attributes with the same name. Cheers and a happy 2021 with two doses of vaccine for you and your loved ones, Raymond! ---------- _______________________________________ Python tracker <report@bugs.python.org> <https://bugs.python.org/issue42781> _______________________________________