One of the open issues fromPEP 3134 is suppressing context: currentlythere is no way to do it. This PEP proposes one.
There are two basic ways to generate exceptions:
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)exceptException:raiseDbfError(...)
Whatever the original exception was (ValueError,TypeError, orsomething else) is irrelevant. The exception from this point on is aDbfError, and the original exception is of no value. However, ifthis exception is printed, we would currently see both.
Several possibilities have been put forth:
raiseasNewException()Reuses theas keyword; can be confusing since we are not reallyreraising the originating exception
raiseNewException()fromNoneFollows existing syntax of explicitly declaring the originatingexception
exc=NewException();exc.__context__=None;raiseexcVery verbose way of the previous method
raiseNewException.no_context(...)Make context suppression a class method.
All of the above options will require changes to the core.
I propose going with the second option:
raiseNewExceptionfromNone
It has the advantage of using the existing pattern of explicitly settingthe cause:
raiseKeyError()fromNameError()
but because the cause isNone the previous context is not displayedby the default exception printing routines.
Note: after acceptance of this PEP, a cleaner implementation mechanismwas proposed and accepted inPEP 415. Refer to that PEP for moredetails on the implementation actually used in Python 3.3.
Currently,None is the default for both__context__ and__cause__.In order to supportraise...fromNone (which would set__cause__ toNone) we need a different default value for__cause__. Several ideaswere put forth on how to implement this at the language level:
__cause__ atNone).Rejected as this can seriously hinder debugging due topoor error messages.
__cause__:False would be thedefault value, and would be replaced whenfrom... was used with theexplicitly chained exception orNone.Rejected as this encourages the use of two different objects types for__cause__ with one of them (boolean) not allowed to have the full rangeof possible values (True would never be used).
__NoException__.Rejected as possibly confusing, possibly being mistakenly raised by users,and not being a truly unique value asNone,True, andFalse are.
Ellipsis as the default value (the... singleton).Accepted.
Ellipses are commonly used in English as place holders when words areomitted. This works in our favor here as a signal that__cause__ isomitted, so look in__context__ for more details.
Ellipsis is not an exception, so cannot be raised.
There is only one Ellipsis, so no unused values.
Error information is not thrown away, so custom code can trace the entireexception chain even if the default code does not.
To supportraiseExceptionfromNone,__context__ will stay as it is,but__cause__ will start out asEllipsis and will change toNonewhen theraiseExceptionfromNone method is used.
| form | __context__ | __cause__ |
|---|---|---|
| raise | None | Ellipsis |
| reraise | previous exception | Ellipsis |
reraise fromNone |ChainedException | previous exception | None | explicitly chained exception |
The default exception printing routine will then:
__cause__ isEllipsis the__context__ (if any) will beprinted.__cause__ isNone the__context__ will not be printed.__cause__ is anything else,__cause__ will be printed.In both of the latter cases the exception chain will stop being followed.
Because the default value for__cause__ is nowEllipsis andraiseExceptionfromCause is simply syntactic sugar for:
_exc=NewException()_exc.__cause__=Cause()raise_exc
Ellipsis, as well asNone, is now allowed as a cause:
raiseExceptionfromEllipsis
There is a patch for CPython implementing this attached toIssue 6210.
Discussion and refinements in thisthread on python-dev.
This document has been placed in the public domain.
Source:https://github.com/python/peps/blob/main/peps/pep-0409.rst
Last modified:2025-02-01 08:59:27 GMT