[Python-checkins] commit of r41339 - peps/trunk

brett.cannon@python.org brett.cannon at python.org
Fri Oct 28 04:53:50 CEST 2005

Author: brett.cannon
Date: Fri Oct 28 04:53:49 2005
New Revision: 41339

Check in initial version of PEP 352: Required Superclass for Exceptions.

Modified: peps/trunk/pep-0000.txt
--- peps/trunk/pep-0000.txt	(original)
+++ peps/trunk/pep-0000.txt	Fri Oct 28 04:53:49 2005
@@ -107,9 +107,10 @@
  S   349  Allow str() to return unicode strings        Schemenauer
  I   350  Codetags                                     Elliott
  S   351  The freeze protocol                          Warsaw
+ S   352  Required Superclass for Exceptions           GvR, Cannon
  S   754  IEEE 754 Floating Point Special Values       Warnes
- Finished PEPs (done, implemented in CVS)
+ Finished PEPs (done, implemented in Subversion)
  SF  100  Python Unicode Integration                   Lemburg
  IF  160  Python 1.6 Release Schedule                  Drake
@@ -398,6 +399,7 @@
  S   349  Allow str() to return unicode strings        Schemenauer
  I   350  Codetags                                     Elliott
  S   351  The freeze protocol                          Warsaw
+ S   352  Required Superclass for Exceptions           GvR, Cannon
  SR  666  Reject Foolish Indentation                   Creighton
  S   754  IEEE 754 Floating Point Special Values       Warnes
  I  3000  Python 3.0 Plans                             Kuchling, Cannon

Added: peps/trunk/pep-0352.txt
--- (empty file)
+++ peps/trunk/pep-0352.txt	Fri Oct 28 04:53:49 2005
@@ -0,0 +1,233 @@
+PEP: 352
+Title: Required Superclass for Exceptions
+Version: $Revision: 1.5 $
+Last-Modified: $Date: 2005/06/07 13:17:37 $
+Author: Brett Cannon <brett at python.org>, Guido van Rossum <guido at python.org>
+Status: Draft
+Type: Standards Track
+Content-Type: text/x-rst
+Created: 27-Oct-2005
+In Python 2.4 and before, any (classic) class can be raised as an
+exception.  The plan is to allow new-style classes starting in Python
+2.5, but this makes the problem worse -- it would mean *any* class (or
+instance) can be raised!  This is a problem since it prevents any
+guarantees to be made about the interface of exceptions.  This PEP
+proposes introducing a new superclass that all raised objects must
+inherit from.  Imposing the restriction will allow a standard
+interface for exceptions to exist that can be relied upon.
+On might counter that requiring a specific base class for a particular
+interface is unPythonic.  However, in the specific case of exceptions
+there's a good reason (which has generally been agreed to on
+python-dev): requiring hierarchy helps code that wants to *catch*
+exceptions by making it possible to catch *all* exceptions explicitly
+by writing ``except BaseException:`` instead of
+``except *:``. [#hierarchy-good]_
+Introducing a new superclass for exceptions also gives us the chance
+to rearrange the exception hierarchy slightly for the better.  As it
+currently stands, all exceptions in the built-in namespace inherit
+from Exception.  This is a problem since this includes two exceptions
+(KeyboardInterrupt and SystemExit) that are usually meant to signal
+that the interpreter should be shut down.  Changing it so that these
+two exceptions inherit from the common superclass instead of Exception
+will make it easy for people to write ``except`` clauses that are not
+overreaching and not catch exceptions that should propagate up and
+terminate the interpreter.
+This PEP is based on previous work done for PEP 348 [#pep348]_.
+Requiring a Common Superclass
+This PEP proposes introducing a new exception named BaseException that
+is a new-style class and has a single attribute, ``message``::
+  class BaseException(object):
+      """Superclass representing the base of the exception hierarchy.
+      Provides a 'message' attribute that contains any argument
+      passed in during instantiation.
+      The 'args' attribute and __getitem__ method are provided for
+      backwards-compatibility and will be deprecated at some point.
+      """
+      def __init__(self, message='', *args):
+          """Set 'message' and 'args' attribute"""
+          self.message = message
+	  self.args = (message,)
+	  if args:
+	      self.args += args
+      def __str__(self):
+	  """Return the str of 'message'"""
+	  if len(self.args) > 1:
+	      return str(self.args)
+	  else:
+	      return str(self.message)
+      def __unicode__(self):
+	  """Return the unicode of 'message'"""
+          if len(self.args) > 1:
+	      return unicode(self.args)
+	  else:
+	      return unicode(self.message)
+      def __repr__(self):
+          if len(self.args) > 1:
+	      args_repr = "*%s" % self.args
+	  else:
+	      args_repr = repr(self.message)
+          return "%s(%s)" % (self.__class__.__name__, args_repr)
+      def __getitem__(self, index):
+          """Index into arguments passed in during instantiation.
+	  Provided for backwards-compatibility and will be
+	  deprecated.
+	  """
+          if index == 0:
+	      return self.message
+	  else:
+	      return self.args[index-1]
+The ``message`` attribute will contain either the argument passed in
+at instantiation of the object or the empty string.  The attribute is
+meant to act as a common location to store any extra information that
+is to be passed along with the exception that goes beyond the location
+of the exception within the exception hierarchy and the exception's
+No restriction is placed upon what may be passed in for ``messsage``.
+This provides backwards-compatibility with how the argument passed
+into Exception has no restrictions.
+The ``args`` attribute is to be deprecated.  While allowing multiple
+arguments to be passed can be helpful, it is in no way essential.  It
+also does not make it necessarily clear which argument is going to be
+represented by the ``__str__`` method.  Restricting to a single
+argument keeps the API simple and clear.  This also means providing a
+``__getitem__`` method is unneeded for exceptions and thus will be
+deprecated as well.
+The ``raise`` statement will be changed to require that any object
+passed to it must inherit from BaseException.  This will make sure
+that all exceptions fall within a single hierarchy that is anchored at
+BaseException [#hierarchy-good]_.  This also guarantees a basic
+interface that is inherited from BaseException.  The change to
+``raise`` will be enforced starting in Python 3.0 (see the `Transition
+Plan`_ below).
+With BaseException being the root of the exception hierarchy,
+Exception will now inherit from it.
+Exception Hierarchy Changes
+With the exception hierarchy now even more important since it has a
+basic root, a change to the existing hierarchy is called for.  As it
+stands now, if one wants to catch all exceptions that signal an error
+*and* do not mean the interpreter should be allowed to exit, you must
+specify all but two exceptions specifically in an ``except`` clause.
+That is needlessly explicit.  This PEP proposes moving
+KeyboardInterrupt and SystemExit to inherit directly from
+Doing this makes catching Exception more reasonable.  It would catch
+only exceptions that signify errors.  Exceptions that signal that the
+intepreter should exit will not be caught and thus be allowed to
+propagate up and allow the interpreter to terminate.
+KeyboardInterrupt has been moved since users typically expect an
+application to exit when the press the interrupt key (usually Ctrl-C).
+If people have overly broad ``except`` clauses the expected behaviour
+does not occur.
+SystemExit has been moved for similar reasons.  Since the exception is
+raised when ``sys.exit()`` is called the interpreter should normally
+be allowed to terminate.  Unfortunately overly broad ``except``
+clauses can prevent the exit to occur which had been explicitly
+To make sure that people catch Exception most of the time, various
+parts of the documentation and tutorials will need to be updated to
+strongly suggest that Exception be what programmers want to use.  Bare
+``except`` clauses or catching BaseException directly should be
+discouraged based on the fact that KeyboardInterrupt and SystemExit
+almost always should be allowed to propagate up.
+Transition Plan
+Since semantic changes to Python are being proposed, a transition plan
+is needed.  The goal is to end up with the new semantics being used in
+Python 3.0 while providing a smooth transition for 2.x code.  All
+deprecations mentioned in the plan will lead to the removal of the
+semantics starting in the version following the introduction of the
+* Python 2.5
+  - introduce BaseException
+    + allow exceptions to be new-style classes
+    + all standard exceptions become new-style classes
+  - Exception, KeyboardInterrupt, and SystemExit inherit from BaseException
+  - deprecate raising string exceptions
+* Python 2.6
+  - deprecate catching string exceptions
+* Python 2.7
+  - deprecate raising exceptions that do not inherit from BaseException
+* Python 2.8
+  - deprecate catching exceptions that do not inherit from BaseException
+  - deprecate ``args`` and ``__getitem__``
+.. [#pep348] PEP 348 (Exception Reorganization for Python 3.0)
+   http://www.python.org/peps/pep-0348.html
+.. [#hierarchy-good] python-dev Summary for 2004-08-01 through 2004-08-15
+   http://www.python.org/dev/summary/2004-08-01_2004-08-15.html#an-exception-is-an-exception-unless-it-doesn-t-inherit-from-exception
+This document has been placed in the public domain.
+   Local Variables:
+   mode: indented-text
+   indent-tabs-mode: nil
+   sentence-end-double-space: t
+   fill-column: 70
+   End:

More information about the Python-checkins mailing list