[Python-Dev] 'hasattr' is broken by design (original) (raw)

Nick Coghlan ncoghlan at gmail.com
Tue Aug 24 00:15:19 CEST 2010


On Tue, Aug 24, 2010 at 7:40 AM, Nick Coghlan <ncoghlan at gmail.com> 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.

Now, it may be worth considering an addition to the inspect module that was basically:

def getattr_static(obj, attr): """Retrieve attributes without triggering dynamic lookup via the descriptor protocol, getattr or getattribute.

    Note: this function may not be able to retrieve all attributes

reported by dir(obj) """ try: instance_dict = object.getattribute(obj, "dict") except AttributeError: pass else: if attr in instance_dict: return instance_dict[attr] for entry in getmro(obj.class): try: return entry.dict[attr] except AttributeError: pass

(not needing to deal with classic classes simplifies things a bit)

So, allowing for the fact that dir() may report attributes that can only be found via dynamic lookup, your get_docstrings example could become something like:

def get_docstrings(obj): try: members = dir(obj) except Exception: members = [] for member in members: try: doc = getattr_static(obj, member).doc except AttributeError: doc = None yield member, doc

Cheers, Nick.

-- Nick Coghlan   |   ncoghlan at gmail.com   |   Brisbane, Australia



More information about the Python-Dev mailing list