[Python-Dev] Re: Dangerous exceptions (was Re:Another test_compilermystery)

Michael Chermside mcherm at mcherm.com
Wed Sep 8 19:19:29 CEST 2004


 [various discussion about how to NOT catch exceptions by default]

I've been working in the Java world for a while now, and they seem
to have solved this problem quite handily -- no one ever seems to
get confused about it. Ignoring Java's "checked exceptions" (which
are a different problem), they've done the following:

   Throwable
   |
   +-- Error
   |   |
   |   +-- OutOfMemorError (and others like it)
   |
   +-- Exception
       |
       +-- IndexOutOfBoundsException (and others like it)
       |
       +-- <user defined exceptions mostly go here>

As I see it, there are several common cases:

  (1) You want to catch a particular (normal) exception.
      (eg: to handle the problem -- this is the normal thing!)
  (2) You want to catch any normal exception.
      (eg: to log and ignore after calls to some subsystem)
  (3) You want to catch a particular special exception
      (eg: to deal with KeyboardInterrupt, or MemoryError)
  (4) You want to catch ANYTHING, then re-throw it afterward
      (eg: to cleanup a DB connection)

We currently make (1) easy (of course!) by writing "except Foo:", and
we make (4) easy by writing "except:" (the bare except). But most
users only want to use (1) and (2)... only experts use (3) and (4).
So I certainly agree that bare except is used by people who want (2)
and should be using (4) instead.

I would think that both the end goal (python 3000) AND the transition
plan are straightforward. For now, a bare except can't be changed
because of backward compatibility. So create a top-level class which
is NOT named "Exception" ("Raisable" anyone?). Our hierarchy would
look like this:

   Raisable
   |
   +-- MemoryError
   +-- SystemExit
   +-- KeyboardInterrupt
   +-- oddballs like ZODB's ConflictError
   |
   +-- Exception
       |
       +-- most everything else
       +-- user defined exceptions


That's not quite as flat as today's hierarchy, but it works pretty
well. When non-experts want to catch all exceptions, if bare excepts
are deprecated, they will write "except Exception:" (that's just
psychology), so most users will wind up with (2) when that's what
they want. Experts can easily do (3) by catching the exception by
name, and experts can do (4) by catching Raisable. When Python 3000
is released and backward compatibility is not required, we can either
remove the bare except, or change it to mean the same as
"except Exception" (Python 3000 will, of course, forbid raising
strings or anything not decended from Raisable).

I don't need anyone to buy into this approach, but since it seems so
straightforward to me I thought I should write it out anyhow.

-- Michael Chermside



More information about the Python-Dev mailing list