Benjamin Peterson wrote:
My question is: Is this a doc bug or a implementation bug? If the former, it will be the description of a data descriptor much less consistent, since it will require that a __get__ method be present, too. If the latter, the fix may break some programs relying on the ability to "cache" a value in the instance dictionary.
[1] http://docs.python.org/reference/datamodel#invoking-descriptors
I would call it a documentation bug: by leaving out the __get__ you're telling Python to override *just* the setting of the attribute, while still using the normal lookup process for retrieving the attribute (i.e. allowing the attribute to be shadowed in the instance dictionary). Adding a "print('Descriptor Invoked')" to the __set__ method in your example:
x = X() print(x.attr) <__main__.Descr object at 0x7f283b51ac50> x.attr = 42 Descriptor invoked print(x.attr) 42 x.attr = 6*9 Descriptor invoked print(x.attr) 54
Note that the behaviour here is still different from that of a data descriptor: with a data descriptor, once it gets shadowed in the instance dictionary, the descriptor is ignored *completely*. The only way to get the descriptor involved again is to eliminate the shadowing. The non-data descriptor with only __set__ is just choosing not to override the attribute lookup process. Cheers, Nick. -- Nick Coghlan | ncoghlan@gmail.com | Brisbane, Australia ---------------------------------------------------------------