On Sat, Apr 11, 2015 at 10:25 PM, Andrew Barnert
On Apr 11, 2015, at 04:29, Chris Angelico
wrote: A bare "except:" clause catches any exception. As of Python 3.0, this can be spelled more explicitly as "except BaseException:", and AFAIK the only difference between the two is that someone might rebind BaseException.
String exceptions were abolished during the 2.x line, without causing major upheaval.
I couldn't remember when this happened, so I look at the docs... But 2.7 (https://docs.python.org/2.7/reference/executionmodel.html#exceptions) still say "Exceptions can also be identified by strings, in which case the except clause is selected by object identity." Do the docs need to be fixed?
1) Yes, sounds like it. 2) By identity? Not by equality?? 3) I have absolutely no idea about string exceptions - I do my best to avoid them. :)
Meanwhile, in the C API (https://docs.python.org/2.7/c-api/exceptions.html#string-exceptions), it says "Changed in version 2.6: All exceptions to be raised or caught must be derived from BaseException." I think that one is correct, but until I sit down at a bigger screen where I can browse the source or run an interpreter, I'm not sure.
Python 2.7.3 (default, Mar 13 2014, 11:03:55) [GCC 4.7.2] on linux2 Type "help", "copyright", "credits" or "license" for more information.
raise 1 Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: exceptions must be old-style classes or derived from BaseException, not int class OldException: pass ... raise OldException Traceback (most recent call last): File "<stdin>", line 1, in <module> __main__.OldException: <__main__.OldException instance at 0x7f0e6c89e1b8>
So that one probably needs a docs change too, although it's not as serious a problem.
Pros: * Remove the attractive nuisance of "hmm, my code's throwing an error that I don't recognize, I'll use try/except" and just catching everything.
But if you just teach people "spell that as except BaseException:" (or, more likely, "... as except Exception:"), it's still the exact same attractive nuisance. And, because "except:" is almost always a red flag in novice code, but "except Exception:" is occasionally reasonable, you're making it a tiny bit harder to spot the mistake when helping novices, without actually fixing it.
(Of course requiring an "as" clause would solve all of this, but nobody wants that...)
So you don't teach people to spell it as "except Exception". You teach them to look up the actual exception type they want to catch. That already happens, but I've seen quite a bit of code from my own students where the shorthand of "except:" is so tempting that it gets in. If that came straight back with SyntaxError, they'd be forced to put _something_ in, and would be more likely to put in a useful exception type.
Cons: * May make it harder to write Py2/Py3-compatible code. In Py2, "except:" will catch old-style-class exceptions.
If the C API docs are right and exceptions must be derived from BaseException even in 2.6, they can't be old-style class instances in the first place. (And if anyone's trying to write 2.5/3.x code, they still have to deal with string exceptions, not to mention that they can't get the value of any exceptions they handle, so they've got much bigger problems.)
Yeah, the wide-span compatibility issue is always going to be there. But given that the docs aren't quite right here, this is an issue with 2.7/3.x code.
Even if that's not right, what problems do old-style classes cause that new-style-but-not-BaseException-derived classes don't?
I don't know. I've never consciously raised or caught an old-style class. If I unwittingly did, there'd be no problem to any of my code if it suddenly started inheriting from Exception or StandardError. ChrisA