Update Rationale.
This commit is contained in:
parent
43671683c9
commit
84ea75eb01
79
pep-0344.txt
79
pep-0344.txt
|
@ -102,22 +102,29 @@ Rationale
|
|||
of tracebacks (from oldest to most recent frame) and because the
|
||||
actual thrown exception is easier to find on the last line.
|
||||
|
||||
Java and Ruby both discard the current exception when an exception
|
||||
occurs in a 'catch'/'rescue' or 'finally'/'ensure' clause. Perl 5
|
||||
lacks built-in structured exception handling. For Perl 6, RFC 88
|
||||
proposes an exception mechanism that retains all the chained
|
||||
exceptions in an array named @@. In that RFC, the most recently
|
||||
raised exception is exposed for matching, as in this PEP; also,
|
||||
arbitrary expressions (possibly involving @@) can be evaluated for
|
||||
exception matching.
|
||||
To keep things simpler, the C API calls for setting an exception
|
||||
will not automatically set the exception's '__context__'. Guido
|
||||
van Rossum has has expressed concerns with making such changes [8].
|
||||
|
||||
As for other languages, Java and Ruby both discard the original
|
||||
exception when another exception occurs in a 'catch'/'rescue' or
|
||||
'finally'/'ensure' clause. Perl 5 lacks built-in structured
|
||||
exception handling. For Perl 6, RFC 88 proposes an exception
|
||||
mechanism that retains chained exceptions in an array named @@.
|
||||
In that RFC, the most recently raised exception is exposed for
|
||||
matching, as in this PEP; also, arbitrary expressions (possibly
|
||||
involving @@) can be evaluated for exception matching.
|
||||
|
||||
Exceptions in C# contain a read-only 'InnerException' property that
|
||||
may point to another exception. This property is not set by the VM
|
||||
automatically. Instead, the constructors of exception objects all
|
||||
accept an optional 'innerException' argument to explicitly set this
|
||||
property. The C# documentation says "an exception that is thrown as
|
||||
a direct result of a previous exception should include a reference
|
||||
to the previous exception in the InnerException property."
|
||||
may point to another exception [9]. According to its documentation,
|
||||
"When an exception X is thrown as a direct result of a previous
|
||||
exception Y, the InnerException property of X should contain a
|
||||
reference to Y." This property is not set by the VM automatically;
|
||||
rather, all exception constructors take an optional 'innerException'
|
||||
argument to set it explicitly. The '__cause__' attribute fulfills
|
||||
the same purpose as InnerException, but this PEP proposes adding a
|
||||
single method to the base Exception class rather than extending the
|
||||
constructors of all exceptions.
|
||||
|
||||
The reason all three of these attributes are presented together in
|
||||
one proposal is that the '__traceback__' attribute provides
|
||||
|
@ -202,7 +209,11 @@ Explicit Exception Chaining
|
|||
The '__cause__' attribute on exception objects is always initialized
|
||||
to None. It is set by calling the 'setcause' method, a new method
|
||||
defined on the base Exception class. For convenience, this method
|
||||
returns the exception itself.
|
||||
returns the exception itself:
|
||||
|
||||
def setcause(self, cause):
|
||||
self.__cause__ = cause
|
||||
return self
|
||||
|
||||
In the following example, a database provides implementations for a
|
||||
few different kinds of storage, with file storage as one kind. The
|
||||
|
@ -301,12 +312,10 @@ Enhanced Reporting
|
|||
|
||||
C API
|
||||
|
||||
To keep things simpler, the PyErr_Set* calls for setting exceptions
|
||||
will not set the '__context__' attribute on exceptions. The BDFL has
|
||||
has expressed qualms with making such changes to PyErr_Set* [8].
|
||||
|
||||
PyErr_NormalizeException will always set the 'traceback' attribute
|
||||
to its 'tb' argument and the '__context__' attribute to None.
|
||||
The PyErr_Set* calls for setting exceptions will not set the
|
||||
'__context__' attribute on exceptions. PyErr_NormalizeException
|
||||
will always set the 'traceback' attribute to its 'tb' argument and
|
||||
the '__context__' and '__cause__' attributes to None.
|
||||
|
||||
A new API function, PyErr_SetContext(context), will help C
|
||||
programmers provide chained exception information. This function
|
||||
|
@ -319,25 +328,28 @@ Compatibility
|
|||
Chained exceptions expose the type of the most recent exception, so
|
||||
they will still match the same 'except' clauses as they do now.
|
||||
|
||||
The proposed changes should not break any code except for code that
|
||||
currently sets or depends on the values of attributes named
|
||||
'__context__', '__cause__', or '__traceback__' on exception
|
||||
instances. As of 2005-05-12, the Python standard library contains
|
||||
no mention of such attributes.
|
||||
The proposed changes should not break any code unless the code sets
|
||||
or uses attributes named '__context__', '__cause__', 'setcause', or
|
||||
'__traceback__' on exception instances. As of 2005-05-12, the
|
||||
Python standard library contains no mention of such attributes.
|
||||
|
||||
|
||||
Open Issues
|
||||
|
||||
Walter Dörwald [9] expressed a desire to attach extra information
|
||||
to an exception during its upward propagation, without changing its
|
||||
Walter Dörwald [10] expressed a desire to attach extra information
|
||||
to an exception during its upward propagation without changing its
|
||||
type. This could be a useful feature, but it is not addressed by
|
||||
this PEP. It could conceivably be addressed by a separate PEP
|
||||
establishing conventions for other informational attributes on
|
||||
exceptions.
|
||||
|
||||
It is not clear whether the '__context__' feature proposed here would
|
||||
be sufficient to cover all the use cases that Raymond Hettinger [1]
|
||||
originally had in mind.
|
||||
It is not clear whether the '__context__' and '__cause__' features
|
||||
proposed here would be sufficient to cover all the use cases that
|
||||
Raymond Hettinger [1] originally had in mind.
|
||||
|
||||
As written, this PEP makes it impossible to suppress '__context__',
|
||||
since setting exc.__context__ to None will only result in it being
|
||||
set again the moment that exc is raised.
|
||||
|
||||
The exception context is lost when a 'yield' statement is executed;
|
||||
resuming the frame after the 'yield' does not restore the context.
|
||||
|
@ -430,7 +442,10 @@ References
|
|||
[8] Guido van Rossum discusses automatic chaining in PyErr_Set*
|
||||
http://mail.python.org/pipermail/python-dev/2003-June/036180.html
|
||||
|
||||
[9] Walter Dörwald suggests wrapping exceptions to add details
|
||||
[9] MSDN .NET Framework Library, "Exception.InnerException Property"
|
||||
http://msdn.microsoft.com/library/en-us/cpref/html/frlrfsystemexceptionclassinnerexceptiontopic.asp
|
||||
|
||||
[10] Walter Dörwald suggests wrapping exceptions to add details
|
||||
http://mail.python.org/pipermail/python-dev/2003-June/036148.html
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue