Eric Snow added the comment:
Returning None is the right thing here. The default for getattr() is returned
only when it catches an AttributeError (hence the exception is the sentinel, so
to speak, not None. Here's a rough equivalent:
_notset = object()
def getattr(obj, name, default=_notset):
getter = type(obj).__getattribute__
try:
getter(obj, name) # The normal object lookup machinery.
except AttributeError:
if default is _notset:
raise
return default
The underlying lookup machinery isn't the simplest thing to grok. Here is the
gist of what happens:
1. Try a data descriptor.
2. Try the object's __dict__.
3. Try a non-data descriptor.
4. Try __getattr__().
5. raise AttributeError.
Thus the descriptor's __get__() would have to raise AttributeError to trigger
the default. If need be, it should turn None into AttributeError or you can
use some other default than None in your getattr() call and turn None into an
AttributeError yourself.
What about "getattr(x, 'foobar') is equivalent to x.foobar" is not correct? It
doesn't matter if the value came from a descriptor's __get__ or from the
object's __dict__.
----------
nosy: +eric.snow
_______________________________________
Python tracker <[email protected]>
<http://bugs.python.org/issue20864>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe:
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com