[Python-Dev] 'hasattr' is broken by design
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