This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

Author eric.snow
Recipients Martin.Thurau, eric.snow
Date 2014-03-08.00:35:22
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1394238922.65.0.351628878628.issue20864@psf.upfronthosting.co.za>
In-reply-to
Content
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__.
History
Date User Action Args
2014-03-08 00:35:22eric.snowsetrecipients: + eric.snow, Martin.Thurau
2014-03-08 00:35:22eric.snowsetmessageid: <1394238922.65.0.351628878628.issue20864@psf.upfronthosting.co.za>
2014-03-08 00:35:22eric.snowlinkissue20864 messages
2014-03-08 00:35:22eric.snowcreate