[Python-ideas] The AttributeError/__getattr__ mechanism

Andrew Barnert abarnert at yahoo.com
Sun Nov 29 14:31:14 EST 2015


On Nov 29, 2015, at 10:10, 王珺 <wjun77 at gmail.com> wrote:
> 
> > A dedicated subclass of AttributeError to trigger __getattr__ is more natural.
> I mean it's unnatural to convert AttributeError to AttributeDynamicError by property or descriptor.

Again, nobody has suggested that the descriptor protocol should do such a thing, so I don't know why you keep arguing about it.

I did suggest that maybe the property descriptor should do so. Or maybe not. If your only problem with my alternate proposal is something that was included as a "maybe" optional bit in parentheses, then you don't seem to have an actual problem with my alternate proposal.

Which brings us back to the point: My alternate proposal is less disruptive and more backward-compatible. Is there some actual problem with it, or some other reason to prefer your original version?

> Why not use RuntimeError as that of PEP479?

Three reasons:

1. There are thousands of lines of working code that handle AttributeError; forcing them to change to handle RuntimeError would be gratuitous backward incompatibility.

2. RuntimeError suggests that the code did something unexpected wrong, rather than a specific thing, possibly intentionally, that you may want to trap and handle. In PEP 479, this makes sense--it was decided that generators should not raise StopIteration instead of returning, and therefore it is a serious error to do so, not just a normal exception. But raising AttributeError from a property or other descriptor is a perfectly reasonable thing to do. It comes naturally from build-time proxies. It's recommended in the descriptor HOWTO. And so on. It makes perfect sense--and there's no other way to accomplish what it does, either. (How would you implement a write-only property that makes "print(spam.eggs)" raise an AttributeError except by raising it in the property function?)

3. In the vast majority of uses of properties and other descriptors, there is no __getattr__, and AttributeError is exactly what people want there. The only problem to be solved here is the rare but unexpected and annoying interaction of such dynamic AttributeErrors and __getattr__. Preventing descriptors from raising AttributeError even in the common cases to block that rare case is like removing a smudge from your table by disintegrating the table. Yes, the smudge is gone, but you haven't come out ahead.

> And there's no need to write custom property-like descriptor factory when you want to trigger __getattr__, although it may be only a few lines of  code.

Your original suggestion would make it _impossible_ for a descriptor to trigger __getattr__. And so would your suggestion here of converting AttributeError to RuntimeError. That doesn't remove the need; it leaves the need but makes it impossible to satisfy.

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-ideas/attachments/20151129/5cf5b94f/attachment.html>


More information about the Python-ideas mailing list