2007-02-05 17:01:58 -05:00
|
|
|
|
PEP: 3109
|
|
|
|
|
Title: Raising Exceptions in Python 3000
|
|
|
|
|
Version: $Revision$
|
|
|
|
|
Last-Modified: $Date$
|
2010-01-20 20:23:17 -05:00
|
|
|
|
Author: Collin Winter <collinwinter@google.com>
|
2007-08-30 20:17:57 -04:00
|
|
|
|
Status: Final
|
2007-02-05 17:01:58 -05:00
|
|
|
|
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
|
|
|
|
|
=========
|
|
|
|
|
|
2022-01-21 06:03:51 -05:00
|
|
|
|
One of Python's guiding maxims is :pep:`"there should be one -- and
|
|
|
|
|
preferably only one -- obvious way to do it" <20>`. Python 2.x's
|
2007-02-05 17:01:58 -05:00
|
|
|
|
``raise`` statement violates this principle, permitting multiple
|
|
|
|
|
ways of expressing the same thought. For example, these statements
|
|
|
|
|
are equivalent: ::
|
2017-03-24 17:11:33 -04:00
|
|
|
|
|
2007-02-05 17:01:58 -05:00
|
|
|
|
raise E, V
|
2017-03-24 17:11:33 -04:00
|
|
|
|
|
2007-02-05 17:01:58 -05:00
|
|
|
|
raise E(V)
|
2017-03-24 17:11:33 -04:00
|
|
|
|
|
2007-02-05 17:01:58 -05:00
|
|
|
|
There is a third form of the ``raise`` statement, allowing arbitrary
|
|
|
|
|
tracebacks to be attached to an exception [#grammar]_: ::
|
|
|
|
|
|
|
|
|
|
raise E, V, T
|
2017-03-24 17:11:33 -04:00
|
|
|
|
|
2022-01-21 06:03:51 -05:00
|
|
|
|
where T is a traceback. As specified in :pep:`344`,
|
2007-02-05 17:01:58 -05:00
|
|
|
|
exception objects in Python 3.x will possess a ``__traceback__``
|
|
|
|
|
attribute, admitting this translation of the three-expression
|
|
|
|
|
``raise`` statement: ::
|
|
|
|
|
|
|
|
|
|
raise E, V, T
|
2017-03-24 17:11:33 -04:00
|
|
|
|
|
2007-02-05 17:01:58 -05:00
|
|
|
|
is translated to ::
|
|
|
|
|
|
|
|
|
|
e = E(V)
|
|
|
|
|
e.__traceback__ = T
|
|
|
|
|
raise e
|
2017-03-24 17:11:33 -04:00
|
|
|
|
|
2007-02-05 17:01:58 -05:00
|
|
|
|
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.
|
2017-03-24 17:11:33 -04:00
|
|
|
|
|
2007-02-05 17:01:58 -05:00
|
|
|
|
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
|
2022-01-21 06:03:51 -05:00
|
|
|
|
BaseException and its subclasses (:pep:`352`). If ``EXCEPTION``
|
2007-02-05 17:01:58 -05:00
|
|
|
|
is a subclass, it will be called with no arguments to obtain
|
|
|
|
|
an exception instance.
|
2017-03-24 17:11:33 -04:00
|
|
|
|
|
2007-02-05 17:01:58 -05:00
|
|
|
|
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]_. ::
|
|
|
|
|
|
2017-03-24 17:11:33 -04:00
|
|
|
|
PEP 8 doesn't express any preference between the
|
2007-02-05 17:01:58 -05:00
|
|
|
|
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.
|
2017-03-24 17:11:33 -04:00
|
|
|
|
|
2007-02-05 17:01:58 -05:00
|
|
|
|
The BDFL has concurred [#guido-declaration]_ and endorsed the
|
|
|
|
|
consolidation of the several ``raise`` forms.
|
2017-03-24 17:11:33 -04:00
|
|
|
|
|
2007-02-05 17:01:58 -05:00
|
|
|
|
|
|
|
|
|
Grammar Changes
|
|
|
|
|
===============
|
2017-03-24 17:11:33 -04:00
|
|
|
|
|
2007-02-05 17:01:58 -05:00
|
|
|
|
In Python 3, the grammar for ``raise`` statements will change
|
|
|
|
|
from [#grammar]_ ::
|
|
|
|
|
|
|
|
|
|
raise_stmt: 'raise' [test [',' test [',' test]]]
|
2017-03-24 17:11:33 -04:00
|
|
|
|
|
2007-02-05 17:01:58 -05:00
|
|
|
|
to ::
|
|
|
|
|
|
|
|
|
|
raise_stmt: 'raise' [test]
|
2017-03-24 17:11:33 -04:00
|
|
|
|
|
|
|
|
|
|
2007-02-05 17:01:58 -05:00
|
|
|
|
Changes to Builtin Types
|
|
|
|
|
========================
|
2017-03-24 17:11:33 -04:00
|
|
|
|
|
2007-02-05 17:01:58 -05:00
|
|
|
|
Because of its relation to exception raising, the signature for the
|
|
|
|
|
``throw()`` method on generator objects will change, dropping the
|
2022-01-21 06:03:51 -05:00
|
|
|
|
optional second and third parameters. The signature thus changes (:pep:`342`)
|
|
|
|
|
from ::
|
2007-02-05 17:01:58 -05:00
|
|
|
|
|
|
|
|
|
generator.throw(E, [V, [T]])
|
2017-03-24 17:11:33 -04:00
|
|
|
|
|
2007-02-05 17:01:58 -05:00
|
|
|
|
to ::
|
|
|
|
|
|
|
|
|
|
generator.throw(EXCEPTION)
|
2017-03-24 17:11:33 -04:00
|
|
|
|
|
2007-02-05 17:01:58 -05:00
|
|
|
|
Where ``EXCEPTION`` is either a subclass of ``BaseException`` or an
|
|
|
|
|
instance of a subclass of ``BaseException``.
|
|
|
|
|
|
2017-03-24 17:11:33 -04:00
|
|
|
|
|
2007-02-05 17:01:58 -05:00
|
|
|
|
Semantic Changes
|
|
|
|
|
================
|
|
|
|
|
|
|
|
|
|
In Python 2, the following ``raise`` statement is legal ::
|
|
|
|
|
|
|
|
|
|
raise ((E1, (E2, E3)), E4), V
|
2017-03-24 17:11:33 -04:00
|
|
|
|
|
2007-02-05 17:01:58 -05:00
|
|
|
|
The interpreter will take the tuple's first element as the exception
|
|
|
|
|
type (recursively), making the above fully equivalent to ::
|
|
|
|
|
|
|
|
|
|
raise E1, V
|
2017-03-24 17:11:33 -04:00
|
|
|
|
|
2007-02-05 17:01:58 -05:00
|
|
|
|
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.
|
2017-03-24 17:11:33 -04:00
|
|
|
|
|
2007-02-05 17:01:58 -05:00
|
|
|
|
|
|
|
|
|
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.
|
2017-03-24 17:11:33 -04:00
|
|
|
|
|
2007-02-05 17:01:58 -05:00
|
|
|
|
2. Two-expression ``raise`` statements will be converted from ::
|
2017-03-24 17:11:33 -04:00
|
|
|
|
|
2007-02-05 17:01:58 -05:00
|
|
|
|
raise E, V
|
2017-03-24 17:11:33 -04:00
|
|
|
|
|
2007-02-05 17:01:58 -05:00
|
|
|
|
to ::
|
2017-03-24 17:11:33 -04:00
|
|
|
|
|
2007-02-05 17:01:58 -05:00
|
|
|
|
raise E(V)
|
2017-03-24 17:11:33 -04:00
|
|
|
|
|
2007-02-05 17:01:58 -05:00
|
|
|
|
Two-expression ``throw()`` calls will be converted from ::
|
2017-03-24 17:11:33 -04:00
|
|
|
|
|
2007-02-05 17:01:58 -05:00
|
|
|
|
generator.throw(E, V)
|
2017-03-24 17:11:33 -04:00
|
|
|
|
|
2007-02-05 17:01:58 -05:00
|
|
|
|
to ::
|
2017-03-24 17:11:33 -04:00
|
|
|
|
|
2007-02-05 17:01:58 -05:00
|
|
|
|
generator.throw(E(V))
|
2017-03-24 17:11:33 -04:00
|
|
|
|
|
2007-02-05 17:01:58 -05:00
|
|
|
|
See point #5 for a caveat to this transformation.
|
2017-03-24 17:11:33 -04:00
|
|
|
|
|
2007-02-05 17:01:58 -05:00
|
|
|
|
3. Three-expression ``raise`` statements will be converted from ::
|
|
|
|
|
|
|
|
|
|
raise E, V, T
|
2017-03-24 17:11:33 -04:00
|
|
|
|
|
2007-02-05 17:01:58 -05:00
|
|
|
|
to ::
|
2017-03-24 17:11:33 -04:00
|
|
|
|
|
2007-02-05 17:01:58 -05:00
|
|
|
|
e = E(V)
|
|
|
|
|
e.__traceback__ = T
|
|
|
|
|
raise e
|
2017-03-24 17:11:33 -04:00
|
|
|
|
|
2007-02-05 17:01:58 -05:00
|
|
|
|
Three-expression ``throw()`` calls will be converted from ::
|
2017-03-24 17:11:33 -04:00
|
|
|
|
|
2007-02-05 17:01:58 -05:00
|
|
|
|
generator.throw(E, V, T)
|
2017-03-24 17:11:33 -04:00
|
|
|
|
|
2007-02-05 17:01:58 -05:00
|
|
|
|
to ::
|
2017-03-24 17:11:33 -04:00
|
|
|
|
|
2007-02-05 17:01:58 -05:00
|
|
|
|
e = E(V)
|
|
|
|
|
e.__traceback__ = T
|
|
|
|
|
generator.throw(e)
|
2017-03-24 17:11:33 -04:00
|
|
|
|
|
2007-02-05 17:01:58 -05:00
|
|
|
|
See point #5 for a caveat to this transformation.
|
2017-03-24 17:11:33 -04:00
|
|
|
|
|
2007-02-05 17:01:58 -05:00
|
|
|
|
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.
|
2017-03-24 17:11:33 -04:00
|
|
|
|
|
2007-02-05 17:01:58 -05:00
|
|
|
|
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:
|
2017-03-24 17:11:33 -04:00
|
|
|
|
|
2007-02-05 17:01:58 -05:00
|
|
|
|
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 ::
|
2017-03-24 17:11:33 -04:00
|
|
|
|
|
2007-02-05 17:01:58 -05:00
|
|
|
|
try:
|
|
|
|
|
something()
|
|
|
|
|
except F as V:
|
|
|
|
|
raise F(V)
|
|
|
|
|
except E as V:
|
|
|
|
|
handle(V)
|
2017-03-24 17:11:33 -04:00
|
|
|
|
|
2007-02-05 17:01:58 -05:00
|
|
|
|
This would be better expressed as ::
|
2017-03-24 17:11:33 -04:00
|
|
|
|
|
2007-02-05 17:01:58 -05:00
|
|
|
|
try:
|
|
|
|
|
something()
|
|
|
|
|
except F:
|
|
|
|
|
raise
|
|
|
|
|
except E as V:
|
|
|
|
|
handle(V)
|
2017-03-24 17:11:33 -04:00
|
|
|
|
|
2007-02-09 09:50:40 -05:00
|
|
|
|
2. ``raise E, V`` as a way of "casting" an exception to another
|
|
|
|
|
class. Taking an example from
|
|
|
|
|
distutils.compiler.unixcompiler ::
|
2017-03-24 17:11:33 -04:00
|
|
|
|
|
2007-02-09 09:50:40 -05:00
|
|
|
|
try:
|
|
|
|
|
self.spawn(pp_args)
|
|
|
|
|
except DistutilsExecError as msg:
|
|
|
|
|
raise CompileError(msg)
|
2017-03-24 17:11:33 -04:00
|
|
|
|
|
2007-02-09 09:50:40 -05:00
|
|
|
|
This would be better expressed as ::
|
2017-03-24 17:11:33 -04:00
|
|
|
|
|
2007-02-09 09:50:40 -05:00
|
|
|
|
try:
|
|
|
|
|
self.spawn(pp_args)
|
|
|
|
|
except DistutilsExecError as msg:
|
|
|
|
|
raise CompileError from msg
|
2017-03-24 17:11:33 -04:00
|
|
|
|
|
2007-02-09 09:50:40 -05:00
|
|
|
|
Using the ``raise ... from ...`` syntax introduced in
|
2022-01-21 06:03:51 -05:00
|
|
|
|
:pep:`344`.
|
2007-02-05 17:01:58 -05:00
|
|
|
|
|
|
|
|
|
|
2007-08-30 20:17:57 -04:00
|
|
|
|
Implementation
|
|
|
|
|
==============
|
|
|
|
|
|
2007-08-30 20:18:43 -04:00
|
|
|
|
This PEP was implemented in revision 57783 [#r57783]_.
|
2007-08-30 20:17:57 -04:00
|
|
|
|
|
|
|
|
|
|
2007-02-05 17:01:58 -05:00
|
|
|
|
References
|
|
|
|
|
==========
|
|
|
|
|
|
|
|
|
|
.. [#grammar]
|
2008-10-02 08:51:05 -04:00
|
|
|
|
http://docs.python.org/reference/simple_stmts.html#raise
|
2017-03-24 17:11:33 -04:00
|
|
|
|
|
2007-02-05 17:01:58 -05:00
|
|
|
|
.. [#amk-line-noise]
|
2017-06-11 15:02:39 -04:00
|
|
|
|
https://mail.python.org/pipermail/python-dev/2005-August/055187.html
|
2007-02-05 17:01:58 -05:00
|
|
|
|
|
|
|
|
|
.. [#guido-declaration]
|
2017-06-11 15:02:39 -04:00
|
|
|
|
https://mail.python.org/pipermail/python-dev/2005-August/055190.html
|
2017-03-24 17:11:33 -04:00
|
|
|
|
|
2007-02-05 17:01:58 -05:00
|
|
|
|
.. [#2to3]
|
|
|
|
|
http://svn.python.org/view/sandbox/trunk/2to3/
|
2017-03-24 17:11:33 -04:00
|
|
|
|
|
2007-02-05 17:01:58 -05:00
|
|
|
|
.. [#raise-fixer]
|
|
|
|
|
http://svn.python.org/view/sandbox/trunk/2to3/fixes/fix_raise.py
|
2017-03-24 17:11:33 -04:00
|
|
|
|
|
2007-02-05 17:01:58 -05:00
|
|
|
|
.. [#throw-fixer]
|
|
|
|
|
http://svn.python.org/view/sandbox/trunk/2to3/fixes/fix_throw.py
|
|
|
|
|
|
2007-08-30 20:17:57 -04:00
|
|
|
|
.. [#r57783]
|
|
|
|
|
http://svn.python.org/view/python/branches/py3k/Include/?rev=57783&view=rev
|
|
|
|
|
|
2007-02-05 17:01:58 -05:00
|
|
|
|
|
|
|
|
|
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:
|