I know the issue has been discussed several times already, however I couldn't find any reasonable explanation of its strange behaviour. The main problem with 'hasattr' function is that is swallows all exceptions derived from Exception class. It's a good thing that it doesn't do that with BaseException as it was fixed not a long time ago, but it's definitely not enough.
First of all, this behaviour of 'hasattr' contradicts with the very core principle of python: "Errors should never pass silently." And since 'hasattr' function is in builtins module and is a widely used function it impacts the whole language.
Secondly, take a look at the following:
>>> class Test: ... @property ... def attr(self): ... self['foo'] ... >>> hasattr(Test(), 'attr') False
There can be any exception instead of KeyError in the above snippet of code, but this small example shows how 'hasattr': misleadingly breaks the code logic (1) and masks bug (2). And that's the simplest possible example, there are much more in real life.
While (1) is maybe acceptable for someone, there is no excuse for the (2). Moreover, current 'hasattr' behaviour tremendously complicates use of '__getattribute__' magic. And forget about importlib magic with LazyImports, one 'hasattr' ruins everything by catching ImportError.
1) I propose to change 'hasattr' behaviour in Python 3, making it to swallow only AttributeError exceptions (exactly like 'getattr'). Probably, Python 3.2 release is our last chance.
2) If you afraid that this new behaviour will break too much python 2 code converted with 2to3, we can introduce another 'hasattr' function defined in 2to3 module itself, and make it imported automatically in all files passed through 2to3 transformation pipeline. This new function will mimic 'hasattr' behaviour from python 2 and converted code should work as expected.
- Yury Selivanov, Sprymix Inc. +1-416-509-2807