[Python-Dev] Pre-PEP: Exception Reorganization for Python 3.0
Nick Coghlan
ncoghlan at gmail.com
Tue Aug 2 12:00:42 CEST 2005
Stephen J. Turnbull wrote:
> Now, somebody proposed:
>
> Raisable -+- Exception
> +- ...
> +- ControlFlowException -+- StopIteration
> +- KeyboardInterrupt
>
> As I wrote above, I see no use for that
The use for it is :
try:
# do stuff
except ControlFlowException:
raise
except Raisable:
# handle anything else
Sure, you could write it as:
try:
# do stuff
except (CriticalException, Exception, Warning):
# handle anything else
But the former structure better reflects the programmers intent (handle
everything except control flow exceptions).
It's a fact that Python uses exceptions for control flow - KeyboardInterrupt
[1], StopIteration, SystemExit (and soon to be GeneratorExit as well).
Grouping them under a common parent allows them to be dealt with as a group,
rather than their names being spelt out explicitly.
Actually having this in the exception hierarchy is beneficial from a
pedagogical point of view as well - the hierarchy is practically the first
thing you encounter when you run "help ('exceptions')" at the interactive prompt.
I have a Python 2.5 candidate hierarchy below, which uses dual inheritance to
avoid breaking backward compatibility - any existing except clauses will catch
all of the exceptions they used to catch. The only new inheritance introduced
is to new exceptions, also avoiding backward compatibility problems, as any
existing except clauses will let by all of the exceptions they used to let by.
There are no removals, but the deprecation process is started in order to
change the names of ReferenceError and RuntimeWarning to WeakReferenceError
and SemanticsWarning.
With this hierarchy, the recommended parent class for application errors
becomes Error, and "except Error:" is preferred to any of "except:", "except
Exception:" and "except StandardError:" (although these three continue to
catch everything they used to catch).
The recommended workaround for libraries raising errors which still inherit
directly from Exception is:
try:
# Use library
except (ControlFlowException, CriticalError):
raise
except Exception:
# Do stuff
(Remove the 'Exception' part if the library is so outdated that it still
raises string exceptions)
Applications which use exceptions to control the flow of execution rather than
to indicate an error (e.g. breaking out of multiple nested loops) are free to
use ControlFlowException directly, or else define their own subclasses of
ControlFlowException.
This hierarchy achieves my main goal for the exception reorganisation, which
is to make it easy for scripts and applications to avoid inadvertently
swallowing the control flow exceptions and critical errors, while still being
able to provide generic error handlers for application faults. (Hmm, the
pre-PEP doesn't include that as a goal in the 'Philosophy' section. . .)
Python 2.4 Compatible Improved Exception Hierarchy v 0.1
========================================================
Exception
+-- ControlFlowException (new)
+-- GeneratorExit (new)
+-- StopIteration
+-- SystemExit
+-- KeyboardInterrupt (dual-inheritance new)
+-- StandardError
+-- KeyboardInterrupt (dual-inheritance new)
+-- CriticalError (new)
+-- MemoryError
+-- SystemError
+-- Error (new)
+-- AssertionError
+-- AttributeError
+-- EOFError
+-- ImportError
+-- TypeError
+-- ReferenceError (deprecated), WeakReferenceError (new alias)
+-- ArithmeticError
+-- FloatingPointError
+-- DivideByZeroError
+-- OverflowError
+-- EnvironmentError
+-- OSError
+-- WindowsError
+-- IOError
+-- LookupError
+-- IndexError
+-- KeyError
+-- NameError
+-- UnboundLocalError
+-- RuntimeError
+-- NotImplementedError
+-- SyntaxError
+-- IndentationError
+-- TabError
+-- ValueError
+-- UnicodeError
+-- UnicodeDecodeError
+-- UnicodeEncodeError
+-- UnicodeTranslateError
+-- Warning
+-- DeprecationWarning
+-- FutureWarning
+-- PendingDeprecationWarning
+-- RuntimeWarning (deprecated), SemanticsWarning (new alias)
+-- SyntaxWarning
+-- UserWarning
Cheers,
Nick.
[1] PJE has convinced me that I was right in thinking that KeyboardInterrupt
was a better fit under ControlFlowExceptions than it was under CriticalError.
--
Nick Coghlan | ncoghlan at gmail.com | Brisbane, Australia
---------------------------------------------------------------
http://boredomandlaziness.blogspot.com
More information about the Python-Dev
mailing list