[Python-checkins] r53637 - peps/trunk/pep-0000.txt peps/trunk/pep-3109.txt

collin.winter python-checkins at python.org
Mon Feb 5 23:01:59 CET 2007


Author: collin.winter
Date: Mon Feb  5 23:01:58 2007
New Revision: 53637

Added:
   peps/trunk/pep-3109.txt   (contents, props changed)
Modified:
   peps/trunk/pep-0000.txt
Log:
Add PEP 3109: Raising Exceptions in Python 3000

Modified: peps/trunk/pep-0000.txt
==============================================================================
--- peps/trunk/pep-0000.txt	(original)
+++ peps/trunk/pep-0000.txt	Mon Feb  5 23:01:58 2007
@@ -107,6 +107,7 @@
  S  3106  Revamping dict.keys(), .values() and .items() GvR
  S  3107  Function Annotations                         Winter, Lownds
  I  3108  Standard Library Reorganization              Cannon
+ I  3109  Raising Exceptions in Python 3000            Winter
 
  Finished PEPs (done, implemented in Subversion)
 
@@ -447,6 +448,7 @@
  S  3106  Revamping dict.keys(), .values() and .items()  GvR
  S  3107  Function Annotations                         Winter, Lownds
  I  3108  Standard Library Reorganization              Cannon
+ I  3109  Raising Exceptions in Python 3000            Winter
 
 Key
 

Added: peps/trunk/pep-3109.txt
==============================================================================
--- (empty file)
+++ peps/trunk/pep-3109.txt	Mon Feb  5 23:01:58 2007
@@ -0,0 +1,286 @@
+PEP: 3109
+Title: Raising Exceptions in Python 3000
+Version: $Revision$
+Last-Modified: $Date$
+Author: Collin Winter <collinw at gmail.com>
+Status: Draft
+Type: Standards Track
+Content-Type: text/x-rst
+Created: 19-Jan-2006
+Python-Version: 3.0
+Post-History:
+
+
+Abstract
+========
+
+This PEP introduces changes to Python's mechanisms for raising
+exceptions intended to reduce both line noise and the size of the
+language.
+
+
+Rationale
+=========
+
+One of Python's guiding maxims is "there should be one -- and
+preferably only one -- obvious way to do it" [#zen]_. Python 2.x's
+``raise`` statement violates this principle, permitting multiple
+ways of expressing the same thought. For example, these statements
+are equivalent: ::
+    
+    raise E, V
+    
+    raise E(V)
+    
+There is a third form of the ``raise`` statement, allowing arbitrary
+tracebacks to be attached to an exception [#grammar]_: ::
+
+    raise E, V, T
+    
+where T is a traceback. As specified in PEP 344 [#pep344]_,
+exception objects in Python 3.x will possess a ``__traceback__``
+attribute, admitting this translation of the three-expression
+``raise`` statement: ::
+
+    raise E, V, T
+    
+is translated to ::
+
+    e = E(V)
+    e.__traceback__ = T
+    raise e
+    
+Using these translations, we can reduce the ``raise`` statement from
+four forms to two:
+
+1. ``raise`` (with no arguments) is used to re-raise the active
+   exception in an ``except`` suite.
+   
+2. ``raise EXCEPTION`` is used to raise a new exception. This form has
+   two sub-variants: ``EXCEPTION`` may be an exception class or an
+   instance of an exception class; valid exception classes are
+   BaseException and its subclasses [#pep352]_. If ``EXCEPTION``
+   is a subclass, it will be called with no arguments to obtain
+   an exception instance.
+   
+   To raise anything else is an error.
+
+There is a further, more tangible benefit to be obtained through this
+consolidation, as noted by A.M. Kuchling [#amk-line-noise]_. ::
+
+    PEP 8 doesn't express any preference between the 
+    two forms of raise statements:
+    raise ValueError, 'blah'
+    raise ValueError("blah")
+
+    I like the second form better, because if the exception arguments
+    are long or include string formatting, you don't need to use line
+    continuation characters because of the containing parens.
+    
+The BDFL has concurred [#guido-declaration]_ and endorsed the
+consolidation of the several ``raise`` forms.
+    
+
+Grammar Changes
+===============
+    
+In Python 3, the grammar for ``raise`` statements will change
+from [#grammar]_ ::
+
+    raise_stmt: 'raise' [test [',' test [',' test]]]
+    
+to ::
+
+    raise_stmt: 'raise' [test]
+    
+    
+Changes to Builtin Types
+========================
+    
+Because of its relation to exception raising, the signature for the
+``throw()`` method on generator objects will change, dropping the
+optional second and third parameters. The signature thus changes 
+from [#throw-sig]_ ::
+
+    generator.throw(E, [V, [T]])
+    
+to ::
+
+    generator.throw(EXCEPTION)
+    
+Where ``EXCEPTION`` is either a subclass of ``BaseException`` or an
+instance of a subclass of ``BaseException``.
+
+    
+Semantic Changes
+================
+
+In Python 2, the following ``raise`` statement is legal ::
+
+    raise ((E1, (E2, E3)), E4), V
+    
+The interpreter will take the tuple's first element as the exception
+type (recursively), making the above fully equivalent to ::
+
+    raise E1, V
+    
+As of Python 3.0, support for raising tuples like this will be
+dropped. This change will bring ``raise`` statements into line with
+the ``throw()`` method on generator objects, which already disallows
+this.
+    
+
+Compatibility Issues
+====================
+
+All two- and three-expression ``raise`` statements will require
+modification, as will all two- and three-expression ``throw()`` calls
+on generators. Fortunately, the translation from Python 2.x to
+Python 3.x in this case is simple and can be handled mechanically
+by Guido van Rossum's 2to3 utility [#2to3]_ using the ``raise`` and
+``throw`` fixers ([#raise-fixer]_, [#throw-fixer]_).
+
+The following translations will be performed:
+
+1. Zero- and one-expression ``raise`` statements will be left
+   intact.
+   
+2. Two-expression ``raise`` statements will be converted from ::
+        
+        raise E, V
+        
+   to ::
+   
+        raise E(V)
+        
+   Two-expression ``throw()`` calls will be converted from ::
+        
+        generator.throw(E, V)
+        
+   to ::
+   
+        generator.throw(E(V))
+        
+   See point #5 for a caveat to this transformation.
+        
+3. Three-expression ``raise`` statements will be converted from ::
+
+        raise E, V, T
+        
+   to ::
+   
+        e = E(V)
+        e.__traceback__ = T
+        raise e
+        
+   Three-expression ``throw()`` calls will be converted from ::
+   
+        generator.throw(E, V, T)
+        
+   to ::
+   
+        e = E(V)
+        e.__traceback__ = T
+        generator.throw(e)
+        
+   See point #5 for a caveat to this transformation.
+        
+4. Two- and three-expression ``raise`` statements where ``E`` is a
+   tuple literal can be converted automatically using ``2to3``'s
+   ``raise`` fixer. ``raise`` statements where ``E`` is a non-literal
+   tuple, e.g., the result of a function call, will need to be
+   converted manually.
+   
+5. Two- and three-expression ``raise`` statements where ``E`` is an
+   exception class and ``V`` is an exception instance will need
+   special attention. These cases break down into two camps:
+   
+   1. ``raise E, V`` as a long-hand version of the zero-argument
+      ``raise`` statement. As an example, assuming F is a subclass
+      of E ::
+      
+          try:
+              something()
+          except F as V:
+              raise F(V)
+          except E as V:
+              handle(V)
+              
+      This would be better expressed as ::
+      
+          try:
+              something()
+          except F:
+              raise
+          except E as V:
+              handle(V)
+              
+    2. ``raise E, V`` as a way of "casting" an exception to another
+       class. Taking an example from
+       distutils.compiler.unixcompiler ::
+       
+            try:
+                self.spawn(pp_args)
+            except DistutilsExecError as msg:
+                raise CompileError(msg)
+                
+       This would be better expressed as ::
+       
+            try:
+                self.spawn(pp_args)
+            except DistutilsExecError as msg:
+                raise CompileError from msg
+   
+       Using the ``raise ... from ...`` syntax introduced in
+       PEP 344.
+
+
+References
+==========
+
+.. [#zen]
+   http://www.python.org/dev/peps/pep-0020/
+   
+.. [#grammar]
+   http://www.python.org/doc/current/ref/raise.html
+   
+.. [#throw-sig]
+   http://www.python.org/dev/peps/pep-0342/
+   
+.. [#pep344]
+   http://www.python.org/dev/peps/pep-0344/
+   
+.. [#pep352]
+   http://www.python.org/dev/peps/pep-0352/
+   
+.. [#amk-line-noise]
+   http://mail.python.org/pipermail/python-dev/2005-August/055187.html
+
+.. [#guido-declaration]
+   http://mail.python.org/pipermail/python-dev/2005-August/055190.html
+   
+.. [#2to3]
+   http://svn.python.org/view/sandbox/trunk/2to3/
+   
+.. [#raise-fixer]
+   http://svn.python.org/view/sandbox/trunk/2to3/fixes/fix_raise.py
+   
+.. [#throw-fixer]
+   http://svn.python.org/view/sandbox/trunk/2to3/fixes/fix_throw.py
+
+
+Copyright
+=========
+
+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
+   coding: utf-8
+   End:


More information about the Python-checkins mailing list