[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