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
|
S 3107 Function Annotations Winter, Lownds
|
||||||
I 3108 Standard Library Reorganization Cannon
|
I 3108 Standard Library Reorganization Cannon
|
||||||
I 3109 Raising Exceptions in Python 3000 Winter
|
I 3109 Raising Exceptions in Python 3000 Winter
|
||||||
|
I 3110 Catching Exceptions in Python 3000 Winter
|
||||||
|
|
||||||
Finished PEPs (done, implemented in Subversion)
|
Finished PEPs (done, implemented in Subversion)
|
||||||
|
|
||||||
|
@ -449,6 +450,7 @@ Numerical Index
|
||||||
S 3107 Function Annotations Winter, Lownds
|
S 3107 Function Annotations Winter, Lownds
|
||||||
I 3108 Standard Library Reorganization Cannon
|
I 3108 Standard Library Reorganization Cannon
|
||||||
I 3109 Raising Exceptions in Python 3000 Winter
|
I 3109 Raising Exceptions in Python 3000 Winter
|
||||||
|
I 3110 Catching Exceptions in Python 3000 Winter
|
||||||
|
|
||||||
Key
|
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