[Python-3000] Pre-peps on raise and except changes (was: Warning for 2.6 and greater)
Collin Winter
collinw at gmail.com
Mon Jan 22 23:45:01 CET 2007
On 1/12/07, Steven Bethard <steven.bethard at gmail.com> wrote:
> On 1/12/07, Barry Warsaw <barry at python.org> wrote:
> > It's worth spending time thinking about how we can help ease the
> > transition for each. There may be more thing too. I wonder if it
> > doesn't make sense for all 3xxx PEPs to include a discussion section
> > on porting.
>
> Yeah, when this was talked about last time, I wrote PEP 3002 which
> requests exactly this:
>
> http://www.python.org/dev/peps/pep-3002/
>
> It basically proposes that all backwards-incompatible changes be
> discussed in a PEP somewhere, and that code like Anthony's be added to
> 2.X to ease the transition.
Attached are drafts of the PEP 3002-compliant PEPs concerning the
changes to raise and except statements that have been discussed on
python-3000.
Any suggestions/corrections/additions would be much appreciated.
Thanks,
Collin Winter
-------------- next part --------------
PEP: 310?
Title: Except Statements 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: 16-Jan-2006
Python-Version: 3.0
Post-History:
Abstract
========
This PEP introduces a changes to ``except`` statements in Python 3.0
intended to help reduce ambiguities in Python's grammar, simplify
exception classes and simplify garbage collection for exceptions.
Rationale
=========
``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>):
In addition, Python 3 will introduce a further incompatibility. 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.
Both of these issues will be resolved by changing Python's grammar.
Lastly, as specified in PEP 344 [#pep344]_, Python 3 exceptions will
possess a ``__traceback__`` attribute. The Open Issues section of that
PEP includes a paragraph on garbage collection difficulties caused by
this attribute, such as a ``exception -> traceback -> stack frame
-> exception'' reference cycle, keeping all locals in scope until the
next GC run. This PEP intends to resolve this issue by adding a
cleanup semantic to ``except`` clauses of the form ``except E as N``.
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 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:
...
except E as N:
...
...
is translated to ::
try:
...
except E as N:
...
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:
...
...
is translated to ::
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.
References
==========
.. [#pep352]
http://www.python.org/dev/peps/pep-0352/
.. [#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
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:
-------------- next part --------------
PEP: 310?
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 a changes to exception raising mechanisms in
Python 3.0 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. Note that attaching the traceback in this
manner *requires* use of the ``raise E, V`` form. 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
The ease of this translation allows a further simplification of the
language by removing the need for the ``raise E, V, T`` form.
There is a further, more tangible benefit to be obtained through this
consildation, 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]
Other Changes
=============
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, [T, [V]])
to ::
generator.throw(E)
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))
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)
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/
.. [#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-3000
mailing list