[Python-checkins] python/nondist/peps pep-0348.txt,1.7,1.8

bcannon@users.sourceforge.net bcannon at users.sourceforge.net
Mon Aug 15 06:28:39 CEST 2005


Update of /cvsroot/python/python/nondist/peps
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv31789

Modified Files:
	pep-0348.txt 
Log Message:
Big changes:

- Remove proposal of removing WindowsError
- Change bare 'except' proposal to recommend their removal

Minor changes:

- Flesh out arguments for TerminatingException
- Reorganize discussion of hierarchy difference compared to 2.4
- Strip out unneeded Rejected Idea sections based on other discussions in the
  PEP


Index: pep-0348.txt
===================================================================
RCS file: /cvsroot/python/python/nondist/peps/pep-0348.txt,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -d -r1.7 -r1.8
--- pep-0348.txt	9 Aug 2005 04:26:28 -0000	1.7
+++ pep-0348.txt	15 Aug 2005 04:28:28 -0000	1.8
@@ -13,25 +13,34 @@
 Abstract
 ========
 
-Python, as 0of version 2.4, has 38 exceptions (including warnings) in
-the built-in namespace in a rather shallow hierarchy.  This list of
-classes has grown over the years without a chance to learn from
+Python, as of version 2.4, has 38 exceptions (including warnings) in
+the built-in namespace in a rather shallow hierarchy.  These
+classes have come about over the years without a chance to learn from
 experience.  This PEP proposes doing a reorganization of the hierarchy
 for Python 3.0 when backwards-compatibility is not as much of an
-issue.  Along with this reorganization, adding a requirement that all
+issue.
+
+Along with this reorganization, adding a requirement that all
 objects passed to a ``raise`` statement must inherit from a specific
-superclass is proposed.  Lastly, bare ``except`` clauses will catch
-only exceptions inheriting from Exception.
+superclass is proposed.  This is to have guarantees about the basic
+interface of exceptions and to further enhance the natural hierarchy
+of exceptions.
 
+Lastly, bare ``except`` clauses will be removed.  While they had their
+usefulness when exceptions could be any object, with the above
+proposal
+of a required superclass for exceptions bare ``except`` clauses lose
+their purpose.
 
-Rationale
-=========
+
+Rationale For Wanting Change
+============================
 
 Exceptions are a critical part of Python.  While exceptions are
 traditionally used to signal errors in a program, they have also grown
 to be used for flow control for things such as iterators.
 
-While their importance is great, there is lack of structure to them.
+While their importance is great, there is a lack of structure to them.
 This stems from the fact that any object can be raised as an
 exception.  Because of this you have no guarantee in terms of what
 kind of object will be raised, destroying any possible hierarchy 
@@ -40,26 +49,23 @@
 But exceptions do have a hierarchy, showing the severity of the
 exception.  The hierarchy also groups related exceptions together to
 simplify catching them in ``except`` clauses.  To allow peopele to
-be able to rely on this hierarchy, a common superclasse that all
+be able to rely on this hierarchy, a common superclass that all
 raise objects must inherit from is being proposed.  It also allows
 guarantees about the interface to raised objects to be made (see
 PEP 344 [#PEP344]_).  A discussion about all of this has occurred
 before on python-dev [#Summary2004-08-01]_.
 
-But allowing a guarantee about the hierarchy is not the only place
-where exceptions can stand improvement.  Bare ``except`` clauses are
-often used in an inappropriate manner.  Since they catch *all* raised
-objects, they can catch exceptions that should have been allowed to
-propagate to the top level of the execution stack, leading to the
-interpreter terminating execution.  Once again, this has been
-discussed on python-dev [#python-dev3]_.
+With the requirement of a common superclass for all exceptions, bare
+``except`` clauses are impacted.  Currently used as a catch-all for
+raised exceptions, its usefulness is terminally weakened.  Now, the
+same functionality is possible by catching the required superclass.
+Once again, this has been discussed on python-dev [#python-dev3]_.
 
-To fix this over-reaching of bare ``except`` clauses, it is being
-proposed that only objects inheriting from Exception be caught by
-bare ``except`` clauses.  This will allow the exception hierarchy
-to be organized in such a way that bare ``except`` clauses can be
-more useful by allowing exceptions that should not normally be caught
-to lead to the termination of the interpreter.
+Finally, slight changes to the exception hierarchy will make it much
+more reasonable in terms of structure.  By minor rearranging
+exceptions
+that should not typically be caught can be allowed to propagate to the
+top of the execution stack, terminating the interpreter as intended.
 
 
 Philosophy of Reorganization
@@ -104,9 +110,6 @@
 .. parsed-literal::
 
    +-- BaseException (new; broader inheritance for subclasses)
-       +-- TerminatingException (new; stricter inheritance for subclasses)
-	   +-- KeyboardInterrupt
-	   +-- SystemExit
        +-- Exception
 	   +-- GeneratorExit (defined in PEP 342 [#PEP342]_)
 	   +-- StandardError
@@ -142,12 +145,17 @@
 	   +-- StopIteration
 	   +-- SystemError
 	   +-- Warning
-	       +-- PendingDeprecationWarning
 	       +-- DeprecationWarning
 	       +-- FutureWarning
-	       +-- SyntaxWarning
+	       +-- PendingDeprecationWarning
 	       +-- RuntimeWarning
+	       +-- SyntaxWarning
 	       +-- UserWarning
+	   + -- WindowsError
+       +-- TerminatingException (new; stricter inheritance for
+				 subclasses)
+	   +-- KeyboardInterrupt
+	   +-- SystemExit
 
 
 Differences Compared to Python 2.4
@@ -157,49 +165,111 @@
 inheritance changes.  Inheritance changes result in either broader or
 more restrictive inheritance.  "Broader" is when a class has an
 inheritance tree like ``cls, A`` and then becomes ``cls, B, A``.
-"Stricter is the reverse.
-
+"Stricter" is the reverse.
 
-New Exceptions
---------------
 
 BaseException
-'''''''''''''
+-------------
 
-The superclass that all exceptions must inherit from.
+The superclass that all exceptions must inherit from.  It's name was
+chosen to reflect that it is at the base of the exception hierarchy
+while being an exception itself.  "Raisable" was considered as a name,
+it was passed on because its name did not properly reflect the fact
+that it is an exception itself.
+
+Direct inheritance of BaseException is not expected, and will
+be discouraged for the general case.  Most user-defined
+exceptions should inherit from Exception instead.  This allows
+catching Exception to continue to work in the common case of catching
+all exceptions that should be caught.  Direct inheritance of
+BaseException should only be done in cases where an entirely new
+category of exception is desired.
+
+But, for cases where all
+exceptions should be caught blindly, ``except BaseException`` will
+work.
 
 
 TerminatingException
-''''''''''''''''''''
+--------------------
 
-Superclass for exceptions that are meant to the termination of the
-interpreter.  It does not inherit from Exception so that
-subclasses are not caught by bare ``except`` clauses.
+Superclass for exceptions that are meant to symbolize the termination
+of
+the interpreter.  It does not inherit from Exception so that the
+common
+``except Exception`` statement does not catch the exceptions.  This
+for ``try`` statements that want to catch all exceptions that are
+signals of errors and handle them separately from exceptions that
+signify that the interpreter should be terminated::
 
-Naming based on the idea that the interpreter is trying to terminate when these
-exceptions are raised.  An earlier proposal suggested "TerminalException" but
-avoidance of any confusion with an actual terminal along with "terminal" being
-more fatalistic than "terminating" led to the current name choice.
+ try:
+     ...
+ # Catch all exceptions that are expected to be caught
+ except Exception:
+     ...
+ # Catch exceptions expected to terminate the interpreter
+ except TerminatingException:
+     ...
 
+Compare this to::
 
-Removed Exceptions
-------------------
+ try:
+     ...
+ except Exception:
+     ...
+ except (KeyboardInterrupt, SystemExit):
+     ...
 
-WindowsError
-''''''''''''
+While more explicit, it is not necessarily obvious why the two
+exceptions are being caught directly.  By providing a common
+superclass with a name that explicitly states the exceptions' typical
+usage the reasoning behind the catch becomes more apparent.
 
-Too OS-specific to be kept in the built-in exception hierarchy.
+Comparing it to an even more general ``except`` clause::
 
+ try:
+     ...
+ except Exception:
+     ...
+ except BaseException:
+     ...
+
+While this will perform the same action and catch all exceptions,
+guaranteed, it is once again not obvious why Exception and
+BaseException are being caught separately and not just
+BaseException based purely on the code.
+
+TerminatingException will also help with transitioning from Python
+2.x to 3.0 .  With TerminatingException being a new exception, when
+it is used the new inheritance for KeyboardInterrupt and SystemExit
+becomes more obvious.
+
+It has been argued that TerminatingException should not be added
+because it goes against Flat Is Better Than Nested (FIBTN).
+While this new exception will not make the hierarchy as flat is it
+could be, the overall depth of the tree is not changed; Exception has
+a much deeper inheritance tree below it.
+
+It has also been argued that since KeyboardInterrupt and SystemExit
+are not caught together that often in 2.4, there might not be much of
+a need for TerminatingException.  But with their new position in the
+hierarchy catching them separately from other exceptions should
+become more prevalent.
+
+Naming is based on the idea that the interpreter is trying to
+terminate when KeyboardInterrupt and SystemExit
+are raised.  An earlier proposal suggested
+"TerminalException" but
+avoidance of any confusion with an actual terminal along with
+"terminal" being
+more fatalistic than "terminating" led to the current name choice.
 
-Change of Position in the Exception Hierarchy
----------------------------------------------
 
 NotImplementedError
-'''''''''''''''''''
+-------------------
 
 Inherits from Exception instead of from RuntimeError.
 
-
 Originally inheriting from RuntimeError, NotImplementedError does not
 have any direct relation to the exception meant for use in user code
 as a quick-and-dirty exception.  Thus it now directly inherits from
@@ -228,27 +298,54 @@
 inheritance check applied.
 
 
-Bare ``except`` Clauses Catching ``Exception`` Only
-===================================================
+Removal of Bare ``except`` Clauses
+==================================
 
-While Python does have its "explicit is better than implicit" tenant,
-it is not necessary if there is a reasonable default behavior.
-Changing the behavior of a bare ``except`` clause makes its existance
-quite reasonable.
+Bare ``except`` clauses serve the purpose of catching all exceptions
+in Python 2.x .  This is needed thanks to the fact that in 2.x any
+exception can be raised as an exception.  But if this PEP is accepted
+this will no longer be the case because of a required superclass for
+all raised objects.  
+This goes against a part of the Zen of Python;
+One Way To Do It (OWTDI) [#zen]_.  By having bare ``except`` clauses
+keep their semantic meaning, there would be two ways of doing the
+same things.  It also goes against Exlpicit Is Better Than Implicit
+(EIBTI) by implicitly doing something that can easily be covered by
+a more explicit statement.
 
-In Python 2.4, a bare ``except`` clause will catch any and all
-exceptions.  Typically, though, this is not what is truly desired.
-More often than not one wants to catch all error exceptions that do
-not signify a "bad" interpreter state.  In the new exception hierarchy
-this is condition is embodied by Exception.  Thus bare ``except``
-clauses will catch only exceptions inheriting from Exception.
+It has also been proposed that bare ``except`` clauses be changed to
+semantically be equivalent to ``except Exception``.  This has been
+proposed since this is what most bare ``except`` clauses are meant to
+do.  This would make ``except`` clauses have a more reasonable
+default behavior.
+
+But this line of reasoning has some issues.  First is that it also
+goes against the Zen of Python; both OWTDI and EIBTI by providing
+an implicit alternative to ``except Exception``.  Secondly,
+backwards-compatibility becomes more difficult.  While removal will
+break code, it can mechanically be changed to have the same semantic
+meaning as it currently has by finding all occurances of ``except:``
+and replacing them with ``except BaseException:``.  But going with
+this semantic change makes compatibility more subtle.  Was a bare
+``except`` clause meant to catch all exceptions, or actually meant
+to catch all reasonable exceptions (i.e., everything but
+TerminatingException)?  Every case will need to be carefully
+examined, and could easily be incorrectly examined, leading to subtle
+bugs.
+
+The shorter typing afforded by bare ``except`` statements also does
+not justify its existence.  "Exception", the typical exception that\
+will be caught, is only nine characters.  Add in the needed space to
+separate "Exception" from "except" you get only 10 more characters to
+type.  While this might be a nuisance in quick-and-dirty scripts, the
+impact is minimal.
 
 
 Implementation
 --------------
 
-In the compiler, when a bare ``except`` clause is reached, the code
-for ``except Exception`` will be emitted.
+Changing Grammar/Grammar is all that is needed to remove bare
+``except`` clauses.
 
 
 Transition Plan
@@ -280,15 +377,6 @@
 in the implementation of the bytecode.
 
 
-Removed Exceptions
-''''''''''''''''''
-
-Exceptions scheduled for removal will be transitioned much like the
-old names of renamed exceptions.  Upon instantiation a
-PendingDeprecationWarning will be raised stating the the exception is
-due for removal in Python 3.0.
-
-
 Required Superclass for ``raise``
 ---------------------------------
 
@@ -299,36 +387,49 @@
 Removal of Bare ``except`` Clauses
 ----------------------------------
 
-A RuntimeWarning will be raised for all bare ``except`` clauses that
-catch an exception that does not inherit from Exception.
-
+A PendingDeprecationWarning will be raised when a bare ``except``
+clause is found in code.  One release before they are removed the
+warning will be changed to DeprecationWarning.
 
-Rejected Ideas
-==============
+Doing ``from __future__ import exceptions`` will cause bare
+``except`` clauses to be considered syntax errors.
 
-Multiple threads on python-dev discussing this PEP have lead to
-various ideas being rejected [#python-dev-thread1]_,
-[#python-dev-thread2]_, [#python-dev-thread3]_.
 
+Roadmap
+-------
 
-KeyboardInterrupt inheriting from ControlFlowException
-------------------------------------------------------
+Python 2.x is the first version that contains changes.  Python 3.0
+will be when transition will be complete.  Version 3.0-1 represents
+one version before 3.0 is released, 3.0-2 two versions before, etc.
 
-KeyboardInterrupt has been a contentious point within this hierarchy.
-Some view the exception more as control flow being caused by the user.
-But with its asynchronous cause (the user is able to trigger the
-exception at any point in code) its proper place is inheriting from
-CriticalError.
+* 2.x
+    - Add BaseException, TerminatingException
+    - Have KeyboardInterrupt and SystemExit inherit from both
+      Exception and TerminatingException
+    - Introduce ``from __future__ import exceptions``
+    - Provide a script that mechanically changes all bare ``except``
+      clauses to catch BaseException in a .py file
+    - PendingDeprecationWarning for bare ``except`` clauses
+    - PendingDeprecationWarning for all objects raised that do not
+      inherit from BaseException
+    - PendingDeprecationWarning raised when KeyboardInterrupt or
+      SystemExit are caught because of their inheritance of Exception
+* 3.0-1
+    - Turn all introduced PendingDeprecationWarnings into
+      DeprecationWarning
+* 3.0
+    - Remove DeprecationWarnings
+    - Have KeyboardInterrupt and SystemExit only inherit from
+      TerminatingException
+    - Remove ``exceptions`` __future__ import support
 
 
-Other Names for BaseException and Exception
--------------------------------------------
+Rejected Ideas
+==============
 
-Alternative names for BaseException and Exception have been
-Raisable/Exception and Exception/StandardError.  The former
-alternatives were rejected because "Raisable" does not reflect its
-exception nature well enough.  The latter alternatives were rejected
-because they do not reflect current use.
+Multiple threads on python-dev discussing this PEP have lead to
+various ideas being rejected [#python-dev-thread1]_,
+[#python-dev-thread2]_, [#python-dev-thread3]_.
 
 
 DeprecationWarning Inheriting From PendingDeprecationWarning
@@ -381,23 +482,14 @@
 
 It has been suggested that ControlFlowException should inherit from
 Exception.  This idea has been rejected based on the thinking that
-control flow exceptions typically should not be caught by bare
-``except`` clauses, whereas Exception subclasses should be.
-
-
-Removal of Bare ``except`` Clauses
-----------------------------------
-
-The suggestion has been made to remove bare ``except`` clauses
-altogether, in the name of "explicit is better than implicit".  But
-Guido has said this is too weak of an argument since other areas of
-Python have default behavior [#python-dev3]_.
-
+control flow exceptions typically do not all need to be caught by a
+single ``except`` clause.
 
 Rename NameError to NamespaceError
 ----------------------------------
 
-NameError is considered more succinct and leaves open no possible mistyping of
+NameError is considered more succinct and leaves open no possible
+mistyping of
 the capitalization of "Namespace" [#python-dev5]_.
 
 
@@ -407,7 +499,8 @@
 The thinking was that RuntimeError was in no way an obvious name for
 an exception meant to be used when a situation did not call for the
 creation of a new exception.  The renaming was rejected on the basis
-that the exception is already used throughout the interpreter [#python-dev6]_.
+that the exception is already used throughout the interpreter
+[#python-dev6]_.
 Rejection of SimpleError was founded on the thought that people
 should be free to use whatever exception they choose and not have one
 so blatently suggested [#python-dev7]_.
@@ -425,26 +518,39 @@
 Have EOFError Subclass IOError
 ------------------------------
 
-The original thought was that sine EOFError deals directly with I/O, it should
-subclass IOError.  But since EOFError is used more as a signal that an event
-has occurred (the exhaustion of an I/O port), it should not subclass such a
-specific error exception.
+The original thought was that since EOFError deals directly with I/O,
+it should
+subclass IOError.  But since EOFError is used more as a signal that an
+event
+has occurred (the exhaustion of an I/O port), it should not subclass
+such a specific error exception.
 
 
 Have MemoryError and SystemError Have a Common Superclass
 ---------------------------------------------------------
 
-Both classes deal with the interpreter, so why not have them have a common
-superclass?  Because one of them means that the interpreter is in a state that
-it should not recover from while the other does not.
+Both classes deal with the interpreter, so why not have them have a
+common
+superclass?  Because one of them means that the interpreter is in a
+state that it should not recover from while the other does not.
 
 
 Common Superclass for PendingDeprecationWarning and DeprecationWarning
 ----------------------------------------------------------------------
 
-Grouping the deprecation warning exceptions together makes intuitive sense.
-But this sensical idea does not extend well when one considers how rarely
-either warning is used, let along at the same time.
+Grouping the deprecation warning exceptions together makes intuitive
+sense.
+But this sensical idea does not extend well when one considers how
+rarely either warning is used, let along at the same time.
+
+
+Removing WindowsError
+---------------------
+
+Originally proposed based on the idea that having such a
+platform-specific exception should not be in the built-in namespace.
+It turns out, though, enough code exists that uses the exception to
+warrant it staying.
 
 
 Acknowledgements
@@ -503,6 +609,9 @@
 .. [#python-dev7] python-dev email (Exception Reorg PEP checked in)
     http://mail.python.org/pipermail/python-dev/2005-August/055175.html
 
+.. [#zen] PEP 20 (The Zen of Python)
+   http://www.python.org/peps/pep-0020.html
+
 
 Copyright
 =========



More information about the Python-checkins mailing list