Add PEP 3110: Catching Exceptions in Python 3000
This commit is contained in:
parent
2b60fcad43
commit
931b82bdc4
|
@ -108,6 +108,7 @@ Index by Category
|
|||
S 3107 Function Annotations Winter, Lownds
|
||||
I 3108 Standard Library Reorganization Cannon
|
||||
I 3109 Raising Exceptions in Python 3000 Winter
|
||||
I 3110 Catching Exceptions in Python 3000 Winter
|
||||
|
||||
Finished PEPs (done, implemented in Subversion)
|
||||
|
||||
|
@ -449,6 +450,7 @@ Numerical Index
|
|||
S 3107 Function Annotations Winter, Lownds
|
||||
I 3108 Standard Library Reorganization Cannon
|
||||
I 3109 Raising Exceptions in Python 3000 Winter
|
||||
I 3110 Catching Exceptions in Python 3000 Winter
|
||||
|
||||
Key
|
||||
|
||||
|
|
|
@ -0,0 +1,287 @@
|
|||
PEP: 3110
|
||||
Title: Catching Exceptions in Python 3000
|
||||
Version: $Revision$
|
||||
Last-Modified: $Date$
|
||||
Author: Collin Winter <collinw@gmail.com>
|
||||
Status: Draft
|
||||
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 ::
|
||||
|
||||
except AttributeError, os.error:
|
||||
|
||||
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.
|
||||
|
||||
|
||||
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
|
||||
...
|
||||
|
||||
An implementation has already been checked into the p3yk branch
|
||||
[#translation-checkin]_.
|
||||
|
||||
|
||||
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.
|
||||
|
||||
|
||||
Open Issues
|
||||
===========
|
||||
|
||||
"except" Statements in Python 2.x
|
||||
-----------------------------------
|
||||
|
||||
It has been proposed that the grammar for ``except`` statements be
|
||||
changed to accommodate both Python 2's ``,`` and Python 3's ``as``
|
||||
between the statement's type and target portions. The grammar
|
||||
would thus change from ::
|
||||
|
||||
except_clause: 'except' [test [',' test]]
|
||||
|
||||
to ::
|
||||
|
||||
except_clause: 'except' [test [('as' | ',') test]]
|
||||
|
||||
It has not been decided whether the proposed end-of-suite cleanup
|
||||
semantic for ``except`` statements should be included in the 2.x
|
||||
series.
|
||||
|
||||
|
||||
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()``.
|
||||
|
||||
|
||||
References
|
||||
==========
|
||||
|
||||
.. [#pep352]
|
||||
http://www.python.org/dev/peps/pep-0352/
|
||||
|
||||
.. [#zen]
|
||||
http://www.python.org/dev/peps/pep-0020/
|
||||
|
||||
.. [#sys-module]
|
||||
http://docs.python.org/lib/module-sys.html
|
||||
|
||||
.. [#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]
|
||||
http://www.python.org/doc/current/ref/try.html
|
||||
|
||||
.. [#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]
|
||||
http://svn.python.org/view/sandbox/trunk/2to3/
|
||||
|
||||
.. [#exceptfixer]
|
||||
http://svn.python.org/view/sandbox/trunk/2to3/fixes/fix_except.py
|
||||
|
||||
.. [#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
|
||||
|
||||
|
||||
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:
|
Loading…
Reference in New Issue