[Python-Dev] 'hasattr' is broken by design
Yury Selivanov
yselivanov at gmail.com
Mon Aug 23 22:50:42 CEST 2010
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
More information about the Python-Dev
mailing list