[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