On 08/23/2010 04:56 PM, Guido van Rossum wrote:
On Mon, Aug 23, 2010 at 7:46 AM, Benjamin Peterson<benjamin@python.org> wrote:
2010/8/23 Yury Selivanov<yselivanov@gmail.com>:
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.
I would be in support of that.
I am cautiously in favor. The existing behavior is definitely a mistake and a trap. But it has been depended on for almost 20 years now.
I'll note that a similar incompatible change has made it to python2.6. This has bitten us in production: class X(object): def __getattr__(self, name): raise KeyError, "error looking for %s" % (name,) def __iter__(self): yield 1 print list(X()) I would expect it to print [1], and in python2.5 it does. In python2.6 it raises a KeyError! The attribute being looked up is an unexpected one: {hrzagude5003}[~]$ python2.6 a.py Traceback (most recent call last): File "a.py", line 8, in <module> print list(X()) File "a.py", line 3, in __getattr__ raise KeyError, "error looking for %s" % (name,) KeyError: 'error looking for __length_hint__' The __length_hint__ lookup expects either no exception or AttributeError, and will propagate others. I'm not sure if this is a bug. On the one hand, throwing anything except AttributeError from __getattr__ is bad style (which is why we fixed the bug by deriving our business exception from AttributeError), but the __length_hint__ check is supposed to be an internal optimization completely invisible to the caller of list(). Being aware that this can be construed as an argument both in favor and against the change at hand, my point is that, if propagating non-AttributeError exceptions is done in checks intended to be invisible, it should certainly be done in hasattr, where it is at least obvious what is being done. Other generic functions and operators, including boolean ones such as ==, happily propagate exceptions. Also, don't expect that this won't break code out there. It certainly will, it's only a matter of assessment whether such code was broken in a different, harder to detect way, to begin with.