classification
Title: Documentation for __getattr__
Type: enhancement Stage: needs patch
Components: Documentation Versions: Python 3.3, Python 3.2, Python 3.1, Python 2.7
process
Status: open Resolution:
Dependencies: Superseder:
Assigned To: docs@python Nosy List: Paul.Davis, docs@python, dstanek, eric.araujo, terry.reedy
Priority: normal Keywords: patch

Created on 2010-05-15 04:10 by Paul.Davis, last changed 2011-03-09 02:39 by terry.reedy.

Files
File name Uploaded Description Edit
example.py Paul.Davis, 2010-05-15 04:10 Short example
Messages (5)
msg105790 - (view) Author: Paul Davis (Paul.Davis) Date: 2010-05-15 04:10
The docs for __getattr__ in the object model section could be more specific on the behavior when a @property raises an AttributeError and there is a custom __getattr__ defined. Specifically, it wasn't exactly clear that __getattr__ would be invoked after a @property was found and evaluated.

The attached script demonstrates the issue on OS X 10.6, Python 2.6.1

I'm thinking something along the lines of:

If the attribute search encounters an AttributeError (perhaps due to a @property raising the error) the search is considered a failure and __getattr__ is invoked.
msg105791 - (view) Author: Paul Davis (Paul.Davis) Date: 2010-05-15 04:13
I should mention, in example.py, it wasn't immediately clear that "print f.bing" would actually print instead of raising the AttributeError. As in, I had a property raising an unexpected error that happend to be an AttributeError. If its not an attribute error, the error is not swallowed. I can see the obvious argument for "AttributeError means not found", it just wasn't immediately obvious what was going on.
msg113192 - (view) Author: Terry J. Reedy (terry.reedy) * (Python committer) Date: 2010-08-07 19:45
The problem with changing 2.7 docs is that object access is different for old- and new-style properties. Does your example work if you remove 'object'? (IE, can old style classes have properties?)

For new-style classes, the example behavior is clear if you 1. know that object has a .__getattribute__ method inherited by everything when not overriden and 2. read the doc for that which says that __getattr__ is called whenever a __getattribute__ call raises AttributeError, which it does here by passing through the .get error.

For 3.x, I think in 3.3.2. Customizing attribute access,
object.__getattr__(self, name) 
"Called when an attribute lookup has not found the attribute in the usual places (i.e. it is not an instance attribute nor is it found in the class tree for self). name is the attribute name. "

might be replaced by

"Called when self.__getattribute__(name) raise AttributeError because name is not an instance attribute, not found in the class tree for self, or is a property attribute whose .get() method raises AttributeError."

But this does not work for 2.7.
msg113193 - (view) Author: Terry J. Reedy (terry.reedy) * (Python committer) Date: 2010-08-07 19:50
/raise/raises/

I am pretty sure that when __getattribute__ is bypassed, so is __getattr__.
msg113212 - (view) Author: Éric Araujo (eric.araujo) * (Python committer) Date: 2010-08-07 21:36
Old-style classes can’t have descriptors, hence no properties, static methods, class methods or super.
History
Date User Action Args
2011-03-09 02:39:38terry.reedysetnosy: terry.reedy, dstanek, eric.araujo, docs@python, Paul.Davis
versions: + Python 3.3
2010-08-18 00:14:47dstaneksetnosy: + dstanek
2010-08-07 21:36:07eric.araujosetnosy: + eric.araujo
messages: + msg113212
2010-08-07 19:50:06terry.reedysetmessages: + msg113193
2010-08-07 19:45:18terry.reedysetversions: - Python 2.6
nosy: + terry.reedy

messages: + msg113192

keywords: + patch
stage: needs patch
2010-07-11 02:18:07terry.reedysetversions: + Python 3.1, Python 2.7, Python 3.2
2010-05-15 04:13:32Paul.Davissetmessages: + msg105791
2010-05-15 04:10:57Paul.Daviscreate