
Guido> I think I didn't pay attention when that was being discussed Guido> before. I definitely don't like to make "except:" mean anyting Guido> besides "catch *all* exceptions."
[Skip]
I agree with you. But much of the time, as http://python.org/sf/411881 demonstrates, "except:" is the wrong answer. If someone wants to catch "everything", they actually don't want to catch SystemExit or KeyboardInterrupt most of the time. That leads to code like
try: fragile_code except (KeyboardInterrupt,SystemExit): raise except: handle_stuff_we_can
or, with your suggestion:
try: fragile_code except (KeyboardInterrupt,SystemExit): raise except Exception, e: handle_stuff_we_can
How often (percentage-wise) do you see that as the catch-all construct? If KeyboardInterrupt inherited from Exception, the above could become:
try: fragile_code except StandardError, e: handle_stuff_we_can
which is much more likely for lazy programmers to write than the first two constructs. (Yes, the laziest people will still use "except:".) All I'm suggesting is that the recommended usage change slightly. (I guess I'd also vote that all exceptions inherit from Exception...)
You're looking at this all wrong. In the past, we've focused on saying "unqualified except is wrong". But IMO "except Exception" or "except StandardError" is just as wrong! You're still catching way more exceptions than is good for you. In the few use cases where you really *do* want to catch (almost) all exceptions, I think it's appropriate that you have to think about the exceptions (pun intended).
Guido> There are too many different use cases to favor a Guido> specific non-obvious; for example, the runcode() method Guido> in class InteractiveInterpreter() in code.py needs to Guido> catch all exceptions including KeyboardInterrupt but Guido> excluding SystemExit. Also note that StopIteration and Guido> the warning categories don't derive from StandardError; Guido> but if any of these is accidentally raised, I'd want my Guido> "except:" clause to catch it! And, while sometimes it's Guido> confusing that SystemExit is caught by "except:", it's Guido> really hard to debug why your program exits without any Guido> warning or traceback when a rogue library function raises Guido> SystemExit.
A couple comments on this:
* I'm not saying you can't use "except:". I'm not advocating a semantic change to the meaning of "except:". (I am suggesting that KeyboardInterrupt should not inherit from StandardError.) I'm saying that the recommended usage for application programmers should be to avoid it.
Sorry. I told you I hadn't read the thread the first time around.
* Special situations will always remain. The point I'm trying to make is that we should make it easier for application programmers to write good code. I don't think specialized standard library code should be held up as typical usage. I'd prefer to have to modify pick over the entire standard library (as I'm already doing) and have it be easier for Joe Programmer to write robust application code than for code.py to be easier to write and have JP naively write less robust code.
We should fix the "except:" examples by catching a very specific error, like AttributeError, TypeError or KeyError. *Not* by catching Exception or StandardError.
* I would hope there are no "rogue" functions in the standard library.
No, but lots of users write them without thinking. E.g. this would seem a common idiom: def error(msg): print "ERROR:", msg sys.exit(1)
If so, we should fix them. As to other people's libraries, we can't do much. SystemExit is a well-defined way to exit the program. If the rogue programmer felt SystemExit was called for at that point, that's between him and the person using his code.
--Guido van Rossum (home page: http://www.python.org/~guido/)