On 2010-08-23, at 4:33 PM, Raymond Hettinger wrote:
On Aug 23, 2010, at 1:03 PM, Guido van Rossum wrote:
But hasattr() has a far different set of use cases, so we should explore an alternate solution to the problem. The usual reason that people use hasattr() instead of getattr() is that they want to check for the presence of of a method/attribute without actually running it, binding it, or triggering any other behavior.
As your example shows, property() defeats this intent by actually executing the code. A better behavior would not run the code at all. It would check the dictionaries along the MRO but not execute any descriptors associated with a given key.
IMO, this is a much better solution, more in line with known use cases for hasattr(). If the proposed change when through, it would fail to address the common use case and cause people to start writing their own versions of hasattr() that just scan but do not run code.
Hm... That sounds like scope creep to me. Properties are supposed to be cheap and idempotent. Trying to figure out whether an attribute exists without using __getattr__ is fraught with problems -- as soon as a class overrides __getattr__ or __getattribute__ you're hosed anyway.
I don't have a specific proposal in mind. My main questions are
* Is there anything that hasattr(obj, key) can or should do that can't already be done with getattr(obj, key, None)? If not, do we really need to change anything?
OK, if my key has None value, how will you detect it with 'getattr'? ... marker = object() ... if (getattr(obj, key, marker) is not marker: Like in the above? Too much code. Ugly code. Just to hide the issue under the carpet.
* Why do people typically use hasattr() instead getattr()? Aren't they are really trying to just determine whether a key exists somewhere in the MRO? If so, then doing anything more than that is probably a surprise.
My example in the initial email clearly showed that sometimes, key is in MRO, but 'hasattr' returns False. For everything in any complicated system (which Python obviously is) should be a strict protocol. In case of properties this protocol is to raise AttributeError if property is missing. Everything else is a potential bug. Current 'hasattr' just masks them. - Yury