[Python-Dev] Pre-PEP: Exception Reorganization for Python 3.0

Nick Coghlan ncoghlan at gmail.com
Sat Jul 30 15:43:30 CEST 2005


M.-A. Lemburg wrote:
> The reason for my -1 on the renaming and reordering is
> that it would completely break compatibility of Python 2.x
> applications with Python 3. Furthermore, there would be next to
> no chance of writing new applications that run in Python 3
> and 2, so you have breakage in both directions.
> 
> Whether this is desired or not is a different discussion,
> I just want to point out some important things to consider:
> 
> When moving from Python 2.x to 3.0, renaming could be solved
> with the help of some scripts, grep et al. However, there
> would have to be a good reason for each of these renamings,
> otherwise this only introduces additional porting overhead.
> Aliases might be a way to provide soft introduction.
> 
> Something that scripts will not be able to help with are
> changes in the inheritance tree, e.g. if an application
> catches a ValueError, the programmer might also expect
> UnicodeErrors to get caught, if the application catches
> a TypeError, this may not be aware that the TypeError could
> actually be an AttributeError.

I think the problems with this can be minimised by avoiding making changes we 
don't need to. I think only a few changes are needed to get a significantly 
cleaner structure.

Here's a fairly minimal proposal, which is closer to the existing 2.4 structure:

New Hierarchy
=============

Raisable (formerly Exception)
+-- CriticalException (new)
     +-- KeyboardInterrupt
     +-- MemoryError
     +-- SystemError
+-- ControlFlowException (new)
     +-- GeneratorExit
     +-- StopIteration
     +-- SystemExit
+-- Exception (formerly StandardError)
     +-- AssertionError
     +-- AttributeError
     +-- ImportError
     +-- TypeError
     +-- WeakReferenceError (formerly ReferenceError)
     +-- ArithmeticError
         +-- FloatingPointError
         +-- DivideByZeroError
         +-- OverflowError
     +-- EnvironmentError
         +-- OSError
             +-- WindowsError (possibly remove this from builtins)
         +-- IOError
             +-- EOFError
     +-- LookupError
         +-- IndexError
         +-- KeyError
     +-- NameError
         +-- UnboundLocalError
     +-- RuntimeError
         +-- NotImplementedError
     +-- SyntaxError
         +-- IndentationError
             +-- TabError
     +-- ValueError
         +-- UnicodeError
             +-- UnicodeDecodeError
             +-- UnicodeEncodeError
             +-- UnicodeTranslateError
+-- Warning
     +-- DeprecationWarning
     +-- FutureWarning
     +-- PendingDeprecationWarning
     +-- SemanticsWarning (formerly RuntimeWarning)
     +-- SyntaxWarning
     +-- UserWarning

Changes from Py 2.4:
====================

The big changes:

   Exception renamed to Raisable
   StandardError renamed to Exception
     Rationale for this renaming is that too many people do "except 
Exception:" when they really mean "except StandardError:". Most applications 
should cope with this semantics change without much hassle, as the only 
exceptions that "slip through the net" are KeyboardInterrupt, MemoryError and 
SystemError.

   New exception ControlFlowException
   Make SystemExit a subclass of this
   Make StopIteration a subclass of this
   Make GeneratorExit a subclass of this
     In Python 2.4, the only two exceptions not under StandardError are 
SystemExit and StopIteration. These are both control flow exceptions - one 
indicates termination of the application, the other indicates completion of an 
iterator. Python 2.5 will most likely add GeneratorExit for termination of a 
generator.
     Grouping these under a common superclass has a few benefits.
       - documentation benefit (its obvious why these exceptions are special)
       - OOWTDI for breaking out of nested loops: raise and catch CFE
       - module developers can use it to clearly mark their own CFE classes

   New exception CriticalException
   Make KeyboardInterrupt a subclass of this
   Make MemoryError a subclass of this
   Make SystemError a subclass of this
     All of these exceptions inherit from StandardError in Python 2.4, but 
each of them indicates something is seriously wrong. KI indicates Ctrl-C has 
been pressed, ME indicates the VM has run out of memory, and SE indicates the 
VM's internals are out of whack. There isn't much a program can or should be 
doing about these. Certainly, none of them should be getting caught by "except 
Exception:".

The following changes are comparatively minor cleanups:

   Make EOFError a subclass of IOError
      Trying to read past the end of a file _is_ an IOError!

   ReferenceError renamed to WeakReferenceError
     This recaptures the context that was lost when making this a builtin.

   RuntimeWarning renamed to SemanticsWarning
     This better captures the meaning of the warning, and avoids confusion 
with RuntimeError, which has a very different purpose.


A few key differences from Brett's original proposal:

   I severely culled the Critical Exceptions list. The CE list was dropped 
back to those where either the user has indicated they want the program to 
stop, or the VM has reported that there is a severe problem. Everything else 
went back under Exception.

   ControlFlowException was made a peer category to Exception and 
CriticalException. This preserves the location of StopIteration. I also added 
SystemExit to this group, because it relates to control flow of the entire 
application (i.e., it is the graceful way to say "get out now").

   AttributeError is left as a standalone exception.

   NameError is not renamed as it actually indicates:
     - this name is not in locals
     - this name is not in any containing lexical scope
     - this name is not in the module globals
     - this name is not in builtins
   UnboundLocalError indicates "this name is in locals, but was referenced 
before it was set". So, I'm not sure what UnboundGlobalError would actually 
_mean_.

   Various other exceptions (RuntimeError, EnvironmentError, etc) either 
weren't deleted or weren't moved. The changes I kept had decent justifications 
for how they improved the clarity of the exception structure - those I dropped 
were those I haven't found convincing.

Cheers,
Nick.

-- 
Nick Coghlan   |   ncoghlan at gmail.com   |   Brisbane, Australia
---------------------------------------------------------------
             http://boredomandlaziness.blogspot.com


More information about the Python-Dev mailing list