[Python-Dev] PEP 409 update [was: PEP 409 - final?]

Yury Selivanov yselivanov.ml at gmail.com
Fri Feb 3 00:32:09 CET 2012


In my opinion using Ellipsis is just wrong.  It is completely 
non-obvious not only to a beginner, but even to an experienced 
python developer.  Writing 'raise Something() from None' 
looks less suspicious, but still strange.

Isn't 'raise Exception().no_context()' or 
'raise Exception().no_cause()' more obvious and easy to
implement?  More readable, less complex and ambiguous.


On 2012-02-02, at 5:10 PM, Ethan Furman wrote:

> 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, 03-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 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 acception; 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                    previous exception  /None/ |
> /None/ | /ChainedException/                         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
> ==========
> 
> 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
> =========
> 
> This document has been placed in the public domain.
> 
> _______________________________________________
> Python-Dev mailing list
> Python-Dev at python.org
> http://mail.python.org/mailman/listinfo/python-dev
> Unsubscribe: http://mail.python.org/mailman/options/python-dev/yselivanov.ml%40gmail.com



More information about the Python-Dev mailing list