[Python-Dev] PEP 409 update [was: PEP 409 (original) (raw)
Yury Selivanov yselivanov.ml at gmail.com
Fri Feb 3 00:32:09 CET 2012
- Previous message: [Python-Dev] PEP 409 update [was: PEP 409 - final?]
- Next message: [Python-Dev] PEP 409 update [was: PEP 409 - final?]
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
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: RevisionRevisionRevision Last-Modified: DateDateDate 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.nocontext(...)/ 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 toIssue 6210
. References ========== Discussion and refinements in thisthread 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
- Previous message: [Python-Dev] PEP 409 update [was: PEP 409 - final?]
- Next message: [Python-Dev] PEP 409 update [was: PEP 409 - final?]
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]