[Python-Dev] 'hasattr' is broken by design

Michael Foord fuzzyman at voidspace.org.uk
Mon Aug 23 23:49:16 CEST 2010


  On 24/08/2010 00:40, Nick Coghlan wrote:
>> Properties are allowed to do whatever the heck they want. That doesn't mean
>> that you have to execute code to determine whether they exist or not.
> If you don't want to execute properties, do the lookup on the type,
> not the instance (obviously, you know the dance you need to do, since
> you've linked the code where you did it). Having apparently simple
> query operations like hasattr/getattr/len/etc execute arbitrary code
> is where much of the language's flexibility comes from, so I don't see
> how it can really be surprising when it happens.

Certainly that is true for len. getattr obviously involves invoking code 
if you are fetching a property or descriptor. No idea how you conclude 
that hasattr executing code adds flexibility to the language though.

Yes I know the dance (walking the mro fetching the attribute out of the 
appropriate type __dict__ or the instance dict - or looking on the 
metaclass if the object you are introspecting is a type itself), it is 
just not trivial - which is why I think it is a shame that people are 
forced to implement it just to ask if a member exists without triggering 
code execution.

> To me, Python's definition of an object having an attribute is "Object
> x has an attribute y if x.y does not raise AttributeError".

Right, and to me Python's object model (the lookup rules hinted at 
above) define whether or not an object "has an attribute" or not. We 
just disagree on this.

However, it is irrelevant so not really worth continuing the discussion. 
Changing hasattr in this way would be backwards incompatible and so 
cannot be done. Doesn't mean I have to like it though. :-)

Michael

> That means
> it can't figure out whether or not the attribute exists without
> actually attempting to retrieve it. There are a few places where we
> instead use a heuristic that says an attribute *probably* exists if it
> appears in the instance dictionary, or in the dictionary of one of the
> types in the MRO, and magic methods have the rule that they must be
> defined on the type rather than the instance in order to count from
> the interpreter's point of view, but neither of those things change
> the basic definition.
>
> For the record, +1 on narrowing the scope of the exception suppression
> in hasattr() to only AttributeError, and adding new C API functions
> that expose the new behaviour. (I've actually long assumed that
> AttributeError *was* the only thing suppressed by hasattr()).
>
> Cheers,
> Nick.
>


-- 
http://www.ironpythoninaction.com/



More information about the Python-Dev mailing list