[Python-Dev] PEP 409 - final?

Ethan Furman ethan at stoneleaf.us
Wed Feb 1 04:57:15 CET 2012


I haven't seen any further discussion here or in the bug tracker. Below 
is the latest version of this PEP, now with a section on Language Details.
Who makes the final call on this? Any idea how long that will take? 
(Not that I'm antsy, or anything... ;)
PEP: 409
Title: Suppressing exception context
Version: $Revision$
Last-Modified: $Date$
Author: Ethan Furman <ethan at stoneleaf.us>
Status: Draft
Type: Standards Track
Content-Type: text/x-rst
Created: 26-Jan-2012
Post-History: 30-Aug-2002, 01-Feb-2012
Abstract
========
One of the open issues from PEP 3134 is suppressing context: currently
there is no way to do it. This PEP proposes one.
Rationale
=========
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(...)
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.
Alternatives
============
Several possibilities have been put forth:
 * ``raise as NewException()``
 Reuses the ``as`` keyword; can be confusing since we are not really
 reraising the originating exception
 * ``raise NewException() from None``
 Follows existing syntax of explicitly declaring the originating
 exception
 * ``exc = NewException(); exc.__context__ = None; raise exc``
 Very verbose way of the previous method
 * ``raise NewException.no_context(...)``
 Make context suppression a class method.
All of the above options will require changes to the core.
Proposal
========
I proprose going with the second option::
 raise NewException from None
It has the advantage of using the existing pattern of explicitly setting
the cause::
 raise KeyError() from NameError()
but because the 'cause' is ``None`` the previous context, while retained,
is not displayed by the default exception printing routines.
Language Details
================
Currently, ``__context__`` and ``__cause__`` start out as None, and then get
set as exceptions occur.
To support ``from None``, ``__context__`` will stay as it is, but
``__cause__`` will start out as ``False``, and will change to ``None``
when the ``raise ... from None`` method is used.
The default exception printing routine will then:
 * If ``__cause__`` is ``False`` 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.
This has the benefit of leaving the ``__context__`` intact for future
logging, querying, etc., while suppressing its display if it is not caught.
This is important for those times when trying to debug poorly written
libraries with `bad error messages`_.
Patches
=======
There is a patch for CPython implementing this attached to `Issue 6210`_.
References
==========
Discussion and refinements in this `thread on python-dev`_.
.. _bad 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
=========
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-Dev mailing list

AltStyle によって変換されたページ (->オリジナル) /