R: [Python-Dev] Deprecating string exceptions

Skip Montanaro skip@pobox.com
Thu, 28 Mar 2002 09:33:51 -0600


>>>>> "Guido" == Guido van Rossum <guido@python.org> writes:

    >> Just to make sure I'm not missing something (I probably am), I still
    >> think the recommended catch-all except construct should become
    >> "except StandardError:" with KeyboardInterrupt migrated to inherit
    >> from Exception instead of StandardError.

    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."

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...)

    Guido> There are too many different use cases to favor a specific
    Guido> non-obvious; for example, the runcode() method in class
    Guido> InteractiveInterpreter() in code.py needs to catch all exceptions
    Guido> including KeyboardInterrupt but excluding SystemExit.  Also note
    Guido> that StopIteration and the warning categories don't derive from
    Guido> StandardError; but if any of these is accidentally raised, I'd
    Guido> want my "except:" clause to catch it!  And, while sometimes it's
    Guido> confusing that SystemExit is caught by "except:", it's really
    Guido> hard to debug why your program exits without any warning or
    Guido> traceback when a rogue library function raises 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.

    * 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.

    * I would hope there are no "rogue" functions in the standard library.
      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.

Skip