Movatterモバイル変換


[0]ホーム

URL:


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

Ethan Furmanethan at stoneleaf.us
Thu Feb 2 23:10:31 CET 2012


PEP: 409Title: Suppressing exception contextVersion: $Revision$Last-Modified: $Date$Author: Ethan Furman <ethan at stoneleaf.us>Status: DraftType: Standards TrackContent-Type: text/x-rstCreated: 26-Jan-2012Post-History: 30-Aug-2002, 01-Feb-2012, 03-Feb-2012Abstract========One of the open issues from PEP 3134 is suppressing context:  currentlythere 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 becomenecessary to raise exceptions; moreover it can be useful, evennecessary, to change from one exception to another.  To take an examplefrom my dbf module:     try:         value = int(value)     except Exception:         raise DbfError(...)Whatever the original exception was (/ValueError/, /TypeError/, orsomething else) is irrelevant.  The exception from this point on is a/DbfError/, and the original exception is of no value.  However, ifthis 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 NoneIt has the advantage of using the existing pattern of explicitly settingthe cause:     raise KeyError() from NameError()but because the cause is /None/ the previous context is not displayedby 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__/.  Severalideas 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.htmlCopyright=========This document has been placed in the public domain.


More information about the Python-Devmailing list

[8]ページ先頭

©2009-2025 Movatter.jp