[Python-checkins] peps: Update from Ethan.
georg.brandl
python-checkins at python.org
Fri Feb 3 09:34:37 CET 2012
http://hg.python.org/peps/rev/d995704c931c
changeset: 4032:d995704c931c
user: Georg Brandl <georg at python.org>
date: Fri Feb 03 09:34:26 2012 +0100
summary:
Update from Ethan.
files:
pep-0409.txt | 128 +++++++++++++++++++++++++++++++-------
1 files changed, 102 insertions(+), 26 deletions(-)
diff --git a/pep-0409.txt b/pep-0409.txt
--- a/pep-0409.txt
+++ b/pep-0409.txt
@@ -7,8 +7,7 @@
Type: Standards Track
Content-Type: text/x-rst
Created: 26-Jan-2012
-Python-Version: 3.3
-Post-History: 2012-01-27
+Post-History: 30-Aug-2002, 01-Feb-2012, 03-Feb-2012
Abstract
@@ -18,48 +17,50 @@
there is no way to do it. This PEP proposes one.
-Motivation
-==========
+Rationale
+=========
-There are two basic ways to generate exceptions: 1) Python does it
-(buggy code, missing resources, ending loops, etc.); and, 2) manually
-(with a raise statement).
+There are two basic ways to generate exceptions:
+
+1. Python does it (buggy code, missing resources, ending loops, etc.)
+
+2. manually (with a raise statement)
When writing libraries, or even just custom classes, it can become
necessary to raise exceptions; moreover it can be useful, even
necessary, to change from one exception to another. To take an
example from my dbf module::
- try:
- value = int(value)
- except Exception:
- raise DbfError(...)
+ try:
+ value = int(value)
+ except Exception:
+ raise DbfError(...)
-Whatever the original exception was (ValueError, TypeError, or
+Whatever the original exception was (``ValueError``, ``TypeError``, or
something else) is irrelevant. The exception from this point on is a
-DbfError, and the original exception is of no value. However, if this
-exception is printed, we would currently see both.
+``DbfError``, and the original exception is of no value. However, if
+this exception is printed, we would currently see both.
Alternatives
============
-
Several possibilities have been put forth:
-- ``raise as NewException()``
+* ``raise as NewException()``
- Reuses the 'as' keyword; can be confusing since we are not really reraising
- the originating exception
+ Reuses the ``as`` keyword; can be confusing since we are not really
+ reraising the originating exception
-- ``raise NewException() from None``
+* ``raise NewException() from None``
- Follows existing syntax of explicitly declaring the originating exception
+ Follows existing syntax of explicitly declaring the originating
+ exception
-- ``exc = NewException(); exc.__context__ = None; raise exc``
+* ``exc = NewException(); exc.__context__ = None; raise exc``
Very verbose way of the previous method
-- ``raise NewException.no_context(...)``
+* ``raise NewException.no_context(...)``
Make context suppression a class method.
@@ -78,15 +79,91 @@
raise KeyError() from NameError()
-but because the 'cause' is None the previous context is discarded.
-There is a patch to this effect attached to issue 6210 [#issue6210]_.
+but because the cause is ``None`` the previous context is not
+displayed by the default exception printing routines.
+
+
+Implementation Discussion
+=========================
+
+Currently, ``None`` is the default for both ``__context__`` and
+``__cause__``. In order to support ``raise ... from None`` (which
+would set ``__cause__`` to ``None``) we need a different default value
+for ``__cause__``. Several ideas were put forth on how to implement
+this at the language level:
+
+* Overwrite the previous exception information (side-stepping the
+ issue and leaving ``__cause__`` at ``None``).
+
+ Rejected as this can seriously hinder debugging due to `poor error
+ messages`_.
+
+* Use one of the boolean values in ``__cause__``: ``False`` would be
+ the default value, and would be replaced when ``from ...`` was used
+ with the explicity chained exception or ``None``.
+
+ Rejected as this encourages the use of two different objects types
+ for ``__cause__`` with one of them (boolean) not allowed to have the
+ full range of possible values (``True`` would never be used).
+
+* Create a special exception class, ``__NoException__``.
+
+ Rejected as possibly confusing, possibly being mistakenly raised by
+ users, and not being a truly unique value as ``None``, ``True``, and
+ ``False`` are.
+
+* Use ``Ellipsis`` as the default value (the ``...`` singleton).
+
+ Accepted. There are no other possible values; it cannot be raised
+ as it is not an exception; it has the connotation of 'fill in the
+ rest...' as in ``__cause__`` is not set, look in ``__context__`` for
+ it.
+
+
+Language Details
+================
+
+To support ``from None``, ``__context__`` will stay as it is, but
+``__cause__`` will start out as ``Ellipsis`` and will change to
+``None`` when the ``raise ... from None`` method is used.
+
+============================================ ================== =======================================
+form __context__ __cause__
+============================================ ================== =======================================
+raise ``None`` ``Ellipsis``
+reraise previous exception ``Ellipsis``
+reraise from ``None`` | ``ChainedException`` previous exception ``None`` | explicitly chained exception
+============================================ ================== =======================================
+
+The default exception printing routine will then:
+
+* If ``__cause__`` is ``Ellipsis`` the ``__context__`` (if any) will
+ be printed.
+
+* If ``__cause__`` is ``None`` the ``__context__`` will not be
+ printed.
+
+* If ``__cause__`` is anything else, ``__cause__`` will be printed.
+
+
+Patches
+=======
+
+There is a patch for CPython implementing this attached to `Issue
+6210`_.
References
==========
-.. [#issue6210]
+Discussion and refinements in this `thread on python-dev`_.
+
+.. _poor error messages:
+ http://bugs.python.org/msg152294
+.. _issue 6210:
http://bugs.python.org/issue6210
+.. _Thread on python-dev:
+ http://mail.python.org/pipermail/python-dev/2012-January/115838.html
Copyright
@@ -95,7 +172,6 @@
This document has been placed in the public domain.
-
..
Local Variables:
mode: indented-text
--
Repository URL: http://hg.python.org/peps
More information about the Python-checkins
mailing list