2007-02-05 17:05:46 -05:00
|
|
|
|
PEP: 3110
|
|
|
|
|
Title: Catching Exceptions in Python 3000
|
|
|
|
|
Version: $Revision$
|
|
|
|
|
Last-Modified: $Date$
|
2010-01-20 20:23:17 -05:00
|
|
|
|
Author: Collin Winter <collinwinter@google.com>
|
2007-05-18 16:30:49 -04:00
|
|
|
|
Status: Final
|
2007-02-05 17:05:46 -05:00
|
|
|
|
Type: Standards Track
|
|
|
|
|
Content-Type: text/x-rst
|
|
|
|
|
Created: 16-Jan-2006
|
|
|
|
|
Python-Version: 3.0
|
|
|
|
|
Post-History:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Abstract
|
|
|
|
|
========
|
|
|
|
|
|
|
|
|
|
This PEP introduces changes intended to help eliminate ambiguities
|
|
|
|
|
in Python's grammar, simplify exception classes, simplify garbage
|
|
|
|
|
collection for exceptions and reduce the size of the language in
|
|
|
|
|
Python 3.0.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Rationale
|
|
|
|
|
=========
|
|
|
|
|
|
|
|
|
|
1. ``except`` clauses in Python 2.x present a syntactic ambiguity
|
|
|
|
|
where the parser cannot differentiate whether ::
|
|
|
|
|
|
|
|
|
|
except <expression>, <expression>:
|
|
|
|
|
|
|
|
|
|
should be interpreted as ::
|
|
|
|
|
|
|
|
|
|
except <type>, <type>:
|
|
|
|
|
|
|
|
|
|
or ::
|
|
|
|
|
|
|
|
|
|
except <type>, <name>:
|
|
|
|
|
|
|
|
|
|
Python 2 opts for the latter semantic, at the cost of requiring the
|
|
|
|
|
former to be parenthesized, like so ::
|
|
|
|
|
|
|
|
|
|
except (<type>, <type>):
|
|
|
|
|
|
|
|
|
|
2. As specified in PEP 352 [#pep352]_, the ability to treat exceptions
|
|
|
|
|
as tuples will be removed, meaning this code will no longer work ::
|
|
|
|
|
|
|
|
|
|
except os.error, (errno, errstr):
|
|
|
|
|
|
|
|
|
|
Because the automatic unpacking will no longer be possible, it is
|
|
|
|
|
desirable to remove the ability to use tuples as ``except`` targets.
|
|
|
|
|
|
|
|
|
|
3. As specified in PEP 344 [#pep344]_, exception instances in Python 3
|
|
|
|
|
will possess a ``__traceback__`` attribute. The Open Issues section
|
|
|
|
|
of that PEP includes a paragraph on garbage collection difficulties
|
|
|
|
|
caused by this attribute, namely a "exception -> traceback ->
|
|
|
|
|
stack frame -> exception" reference cycle, whereby all locals are
|
|
|
|
|
kept in scope until the next GC run. This PEP intends to resolve
|
|
|
|
|
this issue by adding a cleanup semantic to ``except`` clauses in
|
|
|
|
|
Python 3 whereby the target name is deleted at the end of the
|
|
|
|
|
``except`` suite.
|
|
|
|
|
|
|
|
|
|
4. In the spirit of "there should be one -- and preferably only one
|
|
|
|
|
-- obvious way to do it" [#zen]_, it is desirable to consolidate
|
|
|
|
|
duplicate functionality. To this end, the ``exc_value``,
|
|
|
|
|
``exc_type`` and ``exc_traceback`` attributes of the ``sys``
|
|
|
|
|
module [#sys-module]_ will be removed in favor of
|
|
|
|
|
``sys.exc_info()``, which provides the same information. These
|
|
|
|
|
attributes are already listed in PEP 3100 [#pep3100]_ as targeted
|
|
|
|
|
for removal.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Grammar Changes
|
|
|
|
|
===============
|
|
|
|
|
|
|
|
|
|
In Python 3, the grammar for ``except`` statements will change
|
|
|
|
|
from [#grammar]_ ::
|
|
|
|
|
|
|
|
|
|
except_clause: 'except' [test [',' test]]
|
|
|
|
|
|
|
|
|
|
to ::
|
|
|
|
|
|
|
|
|
|
except_clause: 'except' [test ['as' NAME]]
|
|
|
|
|
|
|
|
|
|
The use of ``as`` in place of the comma token means that ::
|
|
|
|
|
|
2008-10-07 12:04:41 -04:00
|
|
|
|
except (AttributeError, os.error):
|
2007-02-05 17:05:46 -05:00
|
|
|
|
|
|
|
|
|
can be clearly understood as a tuple of exception classes. This new
|
|
|
|
|
syntax was first proposed by Greg Ewing [#firstproposal]_ and
|
|
|
|
|
endorsed ([#firstproposal]_, [#renaming]_) by the BDFL.
|
|
|
|
|
|
|
|
|
|
Further, the restriction of the token following ``as`` from ``test``
|
|
|
|
|
to ``NAME`` means that only valid identifiers can be used as
|
|
|
|
|
``except`` targets.
|
|
|
|
|
|
2008-10-07 12:04:41 -04:00
|
|
|
|
Note that the grammar above always requires parenthesized tuples as
|
|
|
|
|
exception clases. That way, the ambiguous ::
|
|
|
|
|
|
|
|
|
|
except A, B:
|
|
|
|
|
|
|
|
|
|
which would mean different things in Python 2.x and 3.x -- leading to
|
|
|
|
|
hard-to-catch bugs -- cannot legally occur in 3.x code.
|
|
|
|
|
|
2007-02-05 17:05:46 -05:00
|
|
|
|
|
|
|
|
|
Semantic Changes
|
|
|
|
|
================
|
|
|
|
|
|
|
|
|
|
In order to resolve the garbage collection issue related to PEP 344,
|
|
|
|
|
``except`` statements in Python 3 will generate additional bytecode to
|
|
|
|
|
delete the target, thus eliminating the reference cycle.
|
|
|
|
|
The source-to-source translation, as suggested by Phillip J. Eby
|
|
|
|
|
[#except-translation]_, is ::
|
|
|
|
|
|
|
|
|
|
try:
|
|
|
|
|
try_body
|
|
|
|
|
except E as N:
|
|
|
|
|
except_body
|
|
|
|
|
...
|
|
|
|
|
|
|
|
|
|
gets translated to (in Python 2.5 terms) ::
|
|
|
|
|
|
|
|
|
|
try:
|
|
|
|
|
try_body
|
|
|
|
|
except E, N:
|
|
|
|
|
try:
|
|
|
|
|
except_body
|
|
|
|
|
finally:
|
|
|
|
|
N = None
|
|
|
|
|
del N
|
|
|
|
|
...
|
|
|
|
|
|
2016-09-06 18:21:13 -04:00
|
|
|
|
An implementation has already been checked into the py3k (formerly
|
|
|
|
|
"p3yk") branch [#translation-checkin]_.
|
2007-02-05 17:05:46 -05:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Compatibility Issues
|
|
|
|
|
====================
|
|
|
|
|
|
|
|
|
|
Nearly all ``except`` clauses will need to be changed. ``except``
|
|
|
|
|
clauses with identifier targets will be converted from ::
|
|
|
|
|
|
|
|
|
|
except E, N:
|
|
|
|
|
|
|
|
|
|
to ::
|
|
|
|
|
|
|
|
|
|
except E as N:
|
|
|
|
|
|
|
|
|
|
``except`` clauses with non-tuple, non-identifier targets
|
|
|
|
|
(e.g., ``a.b.c[d]``) will need to be converted from ::
|
|
|
|
|
|
|
|
|
|
except E, T:
|
|
|
|
|
|
|
|
|
|
to ::
|
|
|
|
|
|
|
|
|
|
except E as t:
|
|
|
|
|
T = t
|
|
|
|
|
|
|
|
|
|
Both of these cases can be handled by Guido van Rossum's ``2to3``
|
|
|
|
|
utility [#2to3]_ using the ``except`` fixer [#exceptfixer]_.
|
|
|
|
|
|
|
|
|
|
``except`` clauses with tuple targets will need to be converted
|
|
|
|
|
manually, on a case-by-case basis. These changes will usually need
|
|
|
|
|
to be accompanied by changes to the exception classes themselves.
|
|
|
|
|
While these changes generally cannot be automated, the ``2to3``
|
|
|
|
|
utility is able to point out cases where the target of an ``except``
|
|
|
|
|
clause is a tuple, simplifying conversion.
|
|
|
|
|
|
|
|
|
|
Situations where it is necessary to keep an exception instance around
|
|
|
|
|
past the end of the ``except`` suite can be easily translated like so
|
|
|
|
|
::
|
|
|
|
|
|
|
|
|
|
try:
|
|
|
|
|
...
|
|
|
|
|
except E as N:
|
|
|
|
|
...
|
|
|
|
|
...
|
|
|
|
|
|
|
|
|
|
becomes ::
|
|
|
|
|
|
|
|
|
|
try:
|
|
|
|
|
...
|
|
|
|
|
except E as N:
|
|
|
|
|
n = N
|
|
|
|
|
...
|
|
|
|
|
...
|
|
|
|
|
|
|
|
|
|
This way, when ``N`` is deleted at the end of the block, ``n`` will
|
|
|
|
|
persist and can be used as normal.
|
|
|
|
|
|
|
|
|
|
Lastly, all uses of the ``sys`` module's ``exc_type``, ``exc_value``
|
|
|
|
|
and ``exc_traceback`` attributes will need to be removed. They can be
|
|
|
|
|
replaced with ``sys.exc_info()[0]``, ``sys.exc_info()[1]`` and
|
|
|
|
|
``sys.exc_info()[2]`` respectively, a transformation that can be
|
|
|
|
|
performed by ``2to3``'s ``sysexcattrs`` fixer.
|
|
|
|
|
|
2007-05-18 16:30:49 -04:00
|
|
|
|
2.6 - 3.0 Compatibility
|
|
|
|
|
-----------------------
|
2007-02-05 17:05:46 -05:00
|
|
|
|
|
2007-05-18 16:30:49 -04:00
|
|
|
|
In order to facilitate forwards compatibility between Python 2.6 and 3.0,
|
|
|
|
|
the ``except ... as ...:`` syntax will be backported to the 2.x series. The
|
|
|
|
|
grammar will thus change from::
|
2007-02-05 17:05:46 -05:00
|
|
|
|
|
|
|
|
|
except_clause: 'except' [test [',' test]]
|
|
|
|
|
|
2007-05-18 16:30:49 -04:00
|
|
|
|
to::
|
2007-02-05 17:05:46 -05:00
|
|
|
|
|
|
|
|
|
except_clause: 'except' [test [('as' | ',') test]]
|
|
|
|
|
|
2007-05-18 16:30:49 -04:00
|
|
|
|
The end-of-suite cleanup semantic for ``except`` statements will not be
|
|
|
|
|
included in the 2.x series of releases.
|
2007-02-05 17:05:46 -05:00
|
|
|
|
|
|
|
|
|
|
2007-05-18 16:30:49 -04:00
|
|
|
|
Open Issues
|
|
|
|
|
===========
|
|
|
|
|
|
2007-02-05 17:05:46 -05:00
|
|
|
|
Replacing or Dropping "sys.exc_info()"
|
|
|
|
|
--------------------------------------
|
|
|
|
|
|
|
|
|
|
The idea of dropping ``sys.exc_info()`` or replacing it with a
|
|
|
|
|
``sys.exception`` attribute or a ``sys.get_exception()`` function
|
|
|
|
|
has been raised several times on python-3000 ([#drop-excinfo]_,
|
|
|
|
|
[#replace-excinfo]_) and mentioned in PEP 344's "Open Issues" section.
|
|
|
|
|
|
|
|
|
|
While a ``2to3`` fixer to replace calls to ``sys.exc_info()``
|
|
|
|
|
and some attribute accesses would be trivial, it would be far more
|
|
|
|
|
difficult for static analysis to find and fix functions that expect
|
|
|
|
|
the values from ``sys.exc_info()`` as arguments. Similarly, this does
|
|
|
|
|
not address the need to rewrite the documentation for all APIs that
|
|
|
|
|
are defined in terms of ``sys.exc_info()``.
|
|
|
|
|
|
|
|
|
|
|
2007-05-18 16:30:49 -04:00
|
|
|
|
Implementation
|
|
|
|
|
==============
|
|
|
|
|
|
|
|
|
|
This PEP was implemented in revisions 53342 [#r53342]_ and 53349
|
2007-05-18 19:14:38 -04:00
|
|
|
|
[#r53349]_. Support for the new ``except`` syntax in 2.6 was
|
|
|
|
|
implemented in revision 55446 [#r55446]_.
|
2007-05-18 16:30:49 -04:00
|
|
|
|
|
|
|
|
|
|
2007-02-05 17:05:46 -05:00
|
|
|
|
References
|
|
|
|
|
==========
|
|
|
|
|
|
|
|
|
|
.. [#pep352]
|
|
|
|
|
http://www.python.org/dev/peps/pep-0352/
|
|
|
|
|
|
|
|
|
|
.. [#zen]
|
|
|
|
|
http://www.python.org/dev/peps/pep-0020/
|
|
|
|
|
|
|
|
|
|
.. [#sys-module]
|
2008-10-02 08:40:49 -04:00
|
|
|
|
http://docs.python.org/library/sys.html
|
2007-02-05 17:05:46 -05:00
|
|
|
|
|
|
|
|
|
.. [#pep3100]
|
|
|
|
|
http://www.python.org/dev/peps/pep-3100/
|
|
|
|
|
|
|
|
|
|
.. [#pep344]
|
|
|
|
|
http://www.python.org/dev/peps/pep-0344/
|
|
|
|
|
|
|
|
|
|
.. [#firstproposal]
|
|
|
|
|
http://mail.python.org/pipermail/python-dev/2006-March/062449.html
|
|
|
|
|
|
|
|
|
|
.. [#renaming]
|
|
|
|
|
http://mail.python.org/pipermail/python-dev/2006-March/062640.html
|
|
|
|
|
|
|
|
|
|
.. [#grammar]
|
2008-10-02 08:51:05 -04:00
|
|
|
|
http://docs.python.org/reference/compound_stmts.html#try
|
2007-02-05 17:05:46 -05:00
|
|
|
|
|
|
|
|
|
.. [#except-translation]
|
|
|
|
|
http://mail.python.org/pipermail/python-3000/2007-January/005395.html
|
|
|
|
|
|
|
|
|
|
.. [#translation-checkin]
|
|
|
|
|
http://svn.python.org/view?rev=53342&view=rev
|
|
|
|
|
|
|
|
|
|
.. [#2to3]
|
2017-01-30 10:29:25 -05:00
|
|
|
|
https://hg.python.org/sandbox/guido/file/2.7/Lib/lib2to3/
|
2007-02-05 17:05:46 -05:00
|
|
|
|
|
|
|
|
|
.. [#exceptfixer]
|
2017-01-30 10:29:25 -05:00
|
|
|
|
https://hg.python.org/sandbox/guido/file/2.7/Lib/lib2to3/fixes/fix_except.py
|
2007-02-05 17:05:46 -05:00
|
|
|
|
|
|
|
|
|
.. [#drop-excinfo]
|
|
|
|
|
http://mail.python.org/pipermail/python-3000/2007-January/005385.html
|
|
|
|
|
|
|
|
|
|
.. [#replace-excinfo]
|
|
|
|
|
http://mail.python.org/pipermail/python-3000/2007-January/005604.html
|
2007-05-18 16:30:49 -04:00
|
|
|
|
|
|
|
|
|
.. [#r53342]
|
2016-09-06 18:21:13 -04:00
|
|
|
|
http://svn.python.org/view?view=revision&revision=53342
|
2007-05-18 16:30:49 -04:00
|
|
|
|
|
|
|
|
|
.. [#r53349]
|
2016-09-06 18:21:13 -04:00
|
|
|
|
http://svn.python.org/view?view=revision&revision=53349
|
2007-05-18 19:14:38 -04:00
|
|
|
|
|
|
|
|
|
.. [#r55446]
|
|
|
|
|
http://svn.python.org/view/python/trunk/?view=rev&rev=55446
|
2007-02-05 17:05:46 -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:
|