IMO (1) or (2) are both acceptable, but I'd prefer (2): swallow 'Exception'. There's a reason why hasattr() is different from getattr() with a default value; it's too early for me to explain it clearly, but I know it was discussed and argued at length when hasattr() was introduced.
I don't see why AssertionError ought to be treated differently than TypeError or any other "regular" error. The key goal here is to avoid swallowing KeyboardInterrupt, and to a lesser extend SystemExit. --Guido On Jan 21, 2008 10:47 PM, Dwayne C. Litzenberger <[EMAIL PROTECTED]> wrote: > This issue has been raised before, but Guido thought that changing things > in 2.x would break too much code. See: > > http://mail.python.org/pipermail/python-dev/2005-February/051770.html > http://mail.python.org/pipermail/python-dev/2005-December/058498.html > http://bugs.python.org/issue504714 > > I'm bringing this up again because the arguments I've seen in favour of > fixing hasattr have been fairly weak, and I'd like to raise some stronger > ones. Also, I haven't seen this issue considered specifically in the > context of Python 3000. > > The problem is that hasattr behaves just like the following code: > > def hasattr(obj, name): > try: > getattr(obj, name) > return True > except: > return False > > In Python 3000, all exceptions inherit from BaseException, so this is > equivalent to: > > def hasattr(obj, name): > try: > getattr(obj, name) > return True > except BaseException: > return False > > There are three major things that are broken by this behaviour, which I > don't think have been explicitly mentioned: > > 1. If the Python interpreter receives SIGINT (usually triggered by > Ctrl-C) while executing obj.__getattr__ (or anything it calls), > hasattr silently returns False and the program continues running. > > Cause: KeyboardInterrupt is swallowed. > > 2. If sys.exit is called within obj.__getattr__, hasattr silently > returns False and the program continues running. > > Cause: SystemExit is swallowed. > > 3. If an assert statement fails within obj.__getattr__, hasattr > silently returns False and the program continues running. > > Cause: AssertionError is swallowed. > > Also, because getattr(x,y,z) swallows only AttributeError, users naturally > expect hasattr to behave the same way. (This argument has been raised > before.) > > I propose a few alternate behaviours for hasattr (and their consequences): > > 1. Swallow only AttributeError. > > - KeyboardInterrupt, SystemExit, and AssertionError are all passed > through, solving all three of the above problems. > > - The behaviour of hasattr is made consistent with getattr(x,y,z). > > 2. Swallow only Exception. > > - KeyboardInterrupt and SystemExit are passed through, but > AssertionError is still swallowed. > > - Breaks less code than the previous option. > > 3. Swallow Exception unless it's an AssertionError. > > - KeyboardInterrupt, SystemExit, and AssertionError are all passed > through, solving all three of the above problems. > > - Kind of ugly. > > 4. Swallow everything except KeyboardInterrupt and SystemExit. > > - AssertionError is still swallowed, but the other problems are > fixed and this probably won't break any existing code. > > I looked at bltinmodule.c, and any of these would be trivial to implement. > > Ideally, I would like to see the first option implemented in Python 3000 > and one of the other options implemented in 2.x. > > -- > Dwayne C. Litzenberger <[EMAIL PROTECTED]> > _______________________________________________ > Python-3000 mailing list > [email protected] > http://mail.python.org/mailman/listinfo/python-3000 > Unsubscribe: > http://mail.python.org/mailman/options/python-3000/guido%40python.org > -- --Guido van Rossum (home page: http://www.python.org/~guido/) _______________________________________________ Python-3000 mailing list [email protected] http://mail.python.org/mailman/listinfo/python-3000 Unsubscribe: http://mail.python.org/mailman/options/python-3000/archive%40mail-archive.com
