I think the real world use case, as property is so common, is just when __getattr__ needed. So anyone using __getattr__ in practice?
Your own examples seem like reasonable uses of __getattr__ to me. But they don't demonstrate your problem, because you don't have any properties, other custom descriptors, or __getattribute__. Do you have any examples that actually do demonstrate the problem to be solved?
> Is that really an imperfection? It says right there in the docs for __getattribute__ that you can delegate to __getattr__ by raising AttributeError
Just like raising StopIteration in generator, as described in PEP479.
But the docs didn't recommend raising StopIteration to exit a generator. The docs implied it by omission, or at least we're ambiguous about what would happen, and you could test it and see that it did, which meant some people took advantage of it to do things like using a StopIteration-throwing function in a comprehension filter clause (with caveats about listcomp vs. genexpr and 2.x vs. 3.x and most readers having to guess why it works). But surely breaking that isn't the same as breaking code that's been explicitly stated to work, and used as sample code, for decades.
Although I'm not sure StopIteration has ever been documented as one way to exit generator. And I admit that an unintentional AttributeError in __getattribute__ is a rare case if ever.
That's my point: "fixing" __getattribute__ to eliminate a "rare case if ever" bug, while also introducing a possibly less-rare backward compatibility problem, seems like a terrible idea. Of course that isn't your intention; it's just a side effect of trying to eliminate a more common bug, with probably rarer intentional uses, in descriptors. But to me, that implies that any solution that can fix descriptors without also "fixing" __getattribute__ is a lot better. And, as you imply in the bug report, this could be done by having either the descriptor mechanism itself, or the object.__getattribute__ implementation, handle AttributeError from descriptor lookup by reraising it as something else.
But still, this is all a minor side issue about choosing between your different variations. The big problem is that I think all of your solutions make it too hard to trigger __getattr__ from a descriptor when you really _do_ want to do so. Maybe you don't want to do so very often, but is it really so rare that we can justify making it impossible? (Especially considering the backward-compat issues for any code that's been doing that for years...)
You didn't comment on the alternative I suggested; would it not satisfy your needs, or have some other problem that makes it unacceptable?