mirror of https://github.com/python/cpython
gh-101100: Improve docs on exception attributes (GH-113057)
* Improve docs on exception attributes * thanks sphinx-lint * fix doctests * argh, okay, give up on doctests * Various improvements
This commit is contained in:
parent
2111795d0c
commit
d05a180350
|
@ -541,7 +541,8 @@ Querying the error indicator
|
|||
|
||||
.. note::
|
||||
|
||||
This function *does not* implicitly set the ``__traceback__``
|
||||
This function *does not* implicitly set the
|
||||
:attr:`~BaseException.__traceback__`
|
||||
attribute on the exception value. If setting the traceback
|
||||
appropriately is desired, the following additional snippet is needed::
|
||||
|
||||
|
@ -753,7 +754,8 @@ Exception Objects
|
|||
.. c:function:: PyObject* PyException_GetTraceback(PyObject *ex)
|
||||
|
||||
Return the traceback associated with the exception as a new reference, as
|
||||
accessible from Python through :attr:`__traceback__`. If there is no
|
||||
accessible from Python through the :attr:`~BaseException.__traceback__`
|
||||
attribute. If there is no
|
||||
traceback associated, this returns ``NULL``.
|
||||
|
||||
|
||||
|
@ -767,8 +769,8 @@ Exception Objects
|
|||
|
||||
Return the context (another exception instance during whose handling *ex* was
|
||||
raised) associated with the exception as a new reference, as accessible from
|
||||
Python through :attr:`__context__`. If there is no context associated, this
|
||||
returns ``NULL``.
|
||||
Python through the :attr:`~BaseException.__context__` attribute.
|
||||
If there is no context associated, this returns ``NULL``.
|
||||
|
||||
|
||||
.. c:function:: void PyException_SetContext(PyObject *ex, PyObject *ctx)
|
||||
|
@ -782,7 +784,8 @@ Exception Objects
|
|||
|
||||
Return the cause (either an exception instance, or ``None``,
|
||||
set by ``raise ... from ...``) associated with the exception as a new
|
||||
reference, as accessible from Python through :attr:`__cause__`.
|
||||
reference, as accessible from Python through the
|
||||
:attr:`~BaseException.__cause__` attribute.
|
||||
|
||||
|
||||
.. c:function:: void PyException_SetCause(PyObject *ex, PyObject *cause)
|
||||
|
@ -791,7 +794,8 @@ Exception Objects
|
|||
it. There is no type check to make sure that *cause* is either an exception
|
||||
instance or ``None``. This steals a reference to *cause*.
|
||||
|
||||
:attr:`__suppress_context__` is implicitly set to ``True`` by this function.
|
||||
The :attr:`~BaseException.__suppress_context__` attribute is implicitly set
|
||||
to ``True`` by this function.
|
||||
|
||||
|
||||
.. c:function:: PyObject* PyException_GetArgs(PyObject *ex)
|
||||
|
|
|
@ -38,36 +38,48 @@ information on defining exceptions is available in the Python Tutorial under
|
|||
Exception context
|
||||
-----------------
|
||||
|
||||
When raising a new exception while another exception
|
||||
is already being handled, the new exception's
|
||||
:attr:`__context__` attribute is automatically set to the handled
|
||||
exception. An exception may be handled when an :keyword:`except` or
|
||||
:keyword:`finally` clause, or a :keyword:`with` statement, is used.
|
||||
.. index:: pair: exception; chaining
|
||||
__cause__ (exception attribute)
|
||||
__context__ (exception attribute)
|
||||
__suppress_context__ (exception attribute)
|
||||
|
||||
This implicit exception context can be
|
||||
supplemented with an explicit cause by using :keyword:`!from` with
|
||||
:keyword:`raise`::
|
||||
Three attributes on exception objects provide information about the context in
|
||||
which an the exception was raised:
|
||||
|
||||
raise new_exc from original_exc
|
||||
.. attribute:: BaseException.__context__
|
||||
BaseException.__cause__
|
||||
BaseException.__suppress_context__
|
||||
|
||||
The expression following :keyword:`from<raise>` must be an exception or ``None``. It
|
||||
will be set as :attr:`__cause__` on the raised exception. Setting
|
||||
:attr:`__cause__` also implicitly sets the :attr:`__suppress_context__`
|
||||
attribute to ``True``, so that using ``raise new_exc from None``
|
||||
effectively replaces the old exception with the new one for display
|
||||
purposes (e.g. converting :exc:`KeyError` to :exc:`AttributeError`), while
|
||||
leaving the old exception available in :attr:`__context__` for introspection
|
||||
when debugging.
|
||||
When raising a new exception while another exception
|
||||
is already being handled, the new exception's
|
||||
:attr:`!__context__` attribute is automatically set to the handled
|
||||
exception. An exception may be handled when an :keyword:`except` or
|
||||
:keyword:`finally` clause, or a :keyword:`with` statement, is used.
|
||||
|
||||
The default traceback display code shows these chained exceptions in
|
||||
addition to the traceback for the exception itself. An explicitly chained
|
||||
exception in :attr:`__cause__` is always shown when present. An implicitly
|
||||
chained exception in :attr:`__context__` is shown only if :attr:`__cause__`
|
||||
is :const:`None` and :attr:`__suppress_context__` is false.
|
||||
This implicit exception context can be
|
||||
supplemented with an explicit cause by using :keyword:`!from` with
|
||||
:keyword:`raise`::
|
||||
|
||||
In either case, the exception itself is always shown after any chained
|
||||
exceptions so that the final line of the traceback always shows the last
|
||||
exception that was raised.
|
||||
raise new_exc from original_exc
|
||||
|
||||
The expression following :keyword:`from<raise>` must be an exception or ``None``. It
|
||||
will be set as :attr:`!__cause__` on the raised exception. Setting
|
||||
:attr:`!__cause__` also implicitly sets the :attr:`!__suppress_context__`
|
||||
attribute to ``True``, so that using ``raise new_exc from None``
|
||||
effectively replaces the old exception with the new one for display
|
||||
purposes (e.g. converting :exc:`KeyError` to :exc:`AttributeError`), while
|
||||
leaving the old exception available in :attr:`!__context__` for introspection
|
||||
when debugging.
|
||||
|
||||
The default traceback display code shows these chained exceptions in
|
||||
addition to the traceback for the exception itself. An explicitly chained
|
||||
exception in :attr:`!__cause__` is always shown when present. An implicitly
|
||||
chained exception in :attr:`!__context__` is shown only if :attr:`!__cause__`
|
||||
is :const:`None` and :attr:`!__suppress_context__` is false.
|
||||
|
||||
In either case, the exception itself is always shown after any chained
|
||||
exceptions so that the final line of the traceback always shows the last
|
||||
exception that was raised.
|
||||
|
||||
|
||||
Inheriting from built-in exceptions
|
||||
|
@ -126,6 +138,12 @@ The following exceptions are used mostly as base classes for other exceptions.
|
|||
tb = sys.exception().__traceback__
|
||||
raise OtherException(...).with_traceback(tb)
|
||||
|
||||
.. attribute:: __traceback__
|
||||
|
||||
A writable field that holds the
|
||||
:ref:`traceback object <traceback-objects>` associated with this
|
||||
exception. See also: :ref:`raise`.
|
||||
|
||||
.. method:: add_note(note)
|
||||
|
||||
Add the string ``note`` to the exception's notes which appear in the standard
|
||||
|
@ -929,8 +947,10 @@ their subgroups based on the types of the contained exceptions.
|
|||
true for the exceptions that should be in the subgroup.
|
||||
|
||||
The nesting structure of the current exception is preserved in the result,
|
||||
as are the values of its :attr:`message`, :attr:`__traceback__`,
|
||||
:attr:`__cause__`, :attr:`__context__` and :attr:`__notes__` fields.
|
||||
as are the values of its :attr:`message`,
|
||||
:attr:`~BaseException.__traceback__`, :attr:`~BaseException.__cause__`,
|
||||
:attr:`~BaseException.__context__` and
|
||||
:attr:`~BaseException.__notes__` fields.
|
||||
Empty nested groups are omitted from the result.
|
||||
|
||||
The condition is checked for all exceptions in the nested exception group,
|
||||
|
@ -956,10 +976,14 @@ their subgroups based on the types of the contained exceptions.
|
|||
and :meth:`split` return instances of the subclass rather
|
||||
than :exc:`ExceptionGroup`.
|
||||
|
||||
:meth:`subgroup` and :meth:`split` copy the :attr:`__traceback__`,
|
||||
:attr:`__cause__`, :attr:`__context__` and :attr:`__notes__` fields from
|
||||
:meth:`subgroup` and :meth:`split` copy the
|
||||
:attr:`~BaseException.__traceback__`,
|
||||
:attr:`~BaseException.__cause__`, :attr:`~BaseException.__context__` and
|
||||
:attr:`~BaseException.__notes__` fields from
|
||||
the original exception group to the one returned by :meth:`derive`, so
|
||||
these fields do not need to be updated by :meth:`derive`. ::
|
||||
these fields do not need to be updated by :meth:`derive`.
|
||||
|
||||
.. doctest::
|
||||
|
||||
>>> class MyGroup(ExceptionGroup):
|
||||
... def derive(self, excs):
|
||||
|
|
|
@ -67,7 +67,8 @@ The module defines the following functions:
|
|||
|
||||
The optional *limit* argument has the same meaning as for :func:`print_tb`.
|
||||
If *chain* is true (the default), then chained exceptions (the
|
||||
:attr:`__cause__` or :attr:`__context__` attributes of the exception) will be
|
||||
:attr:`~BaseException.__cause__` or :attr:`~BaseException.__context__`
|
||||
attributes of the exception) will be
|
||||
printed as well, like the interpreter itself does when printing an unhandled
|
||||
exception.
|
||||
|
||||
|
@ -234,10 +235,11 @@ capture data for later printing in a lightweight fashion.
|
|||
Capture an exception for later rendering. *limit*, *lookup_lines* and
|
||||
*capture_locals* are as for the :class:`StackSummary` class.
|
||||
|
||||
If *compact* is true, only data that is required by :class:`TracebackException`'s
|
||||
``format`` method is saved in the class attributes. In particular, the
|
||||
``__context__`` field is calculated only if ``__cause__`` is ``None`` and
|
||||
``__suppress_context__`` is false.
|
||||
If *compact* is true, only data that is required by
|
||||
:class:`!TracebackException`'s :meth:`format` method
|
||||
is saved in the class attributes. In particular, the
|
||||
:attr:`__context__` field is calculated only if :attr:`__cause__` is
|
||||
``None`` and :attr:`__suppress_context__` is false.
|
||||
|
||||
Note that when locals are captured, they are also shown in the traceback.
|
||||
|
||||
|
@ -255,27 +257,31 @@ capture data for later printing in a lightweight fashion.
|
|||
|
||||
.. attribute:: __cause__
|
||||
|
||||
A :class:`TracebackException` of the original ``__cause__``.
|
||||
A :class:`!TracebackException` of the original
|
||||
:attr:`~BaseException.__cause__`.
|
||||
|
||||
.. attribute:: __context__
|
||||
|
||||
A :class:`TracebackException` of the original ``__context__``.
|
||||
A :class:`!TracebackException` of the original
|
||||
:attr:`~BaseException.__context__`.
|
||||
|
||||
.. attribute:: exceptions
|
||||
|
||||
If ``self`` represents an :exc:`ExceptionGroup`, this field holds a list of
|
||||
:class:`TracebackException` instances representing the nested exceptions.
|
||||
:class:`!TracebackException` instances representing the nested exceptions.
|
||||
Otherwise it is ``None``.
|
||||
|
||||
.. versionadded:: 3.11
|
||||
|
||||
.. attribute:: __suppress_context__
|
||||
|
||||
The ``__suppress_context__`` value from the original exception.
|
||||
The :attr:`~BaseException.__suppress_context__` value from the original
|
||||
exception.
|
||||
|
||||
.. attribute:: __notes__
|
||||
|
||||
The ``__notes__`` value from the original exception, or ``None``
|
||||
The :attr:`~BaseException.__notes__` value from the original exception,
|
||||
or ``None``
|
||||
if the exception does not have any notes. If it is not ``None``
|
||||
is it formatted in the traceback after the exception string.
|
||||
|
||||
|
@ -349,8 +355,8 @@ capture data for later printing in a lightweight fashion.
|
|||
|
||||
Format the exception.
|
||||
|
||||
If *chain* is not ``True``, ``__cause__`` and ``__context__`` will not
|
||||
be formatted.
|
||||
If *chain* is not ``True``, :attr:`__cause__` and :attr:`__context__`
|
||||
will not be formatted.
|
||||
|
||||
The return value is a generator of strings, each ending in a newline and
|
||||
some containing internal newlines. :func:`~traceback.print_exception`
|
||||
|
|
|
@ -1390,7 +1390,8 @@ unwinds the execution stack, at each unwound level a traceback object is
|
|||
inserted in front of the current traceback. When an exception handler is
|
||||
entered, the stack trace is made available to the program. (See section
|
||||
:ref:`try`.) It is accessible as the third item of the
|
||||
tuple returned by :func:`sys.exc_info`, and as the ``__traceback__`` attribute
|
||||
tuple returned by :func:`sys.exc_info`, and as the
|
||||
:attr:`~BaseException.__traceback__` attribute
|
||||
of the caught exception.
|
||||
|
||||
When the program contains no suitable
|
||||
|
|
|
@ -578,7 +578,7 @@ The :dfn:`type` of the exception is the exception instance's class, the
|
|||
.. index:: pair: object; traceback
|
||||
|
||||
A traceback object is normally created automatically when an exception is raised
|
||||
and attached to it as the :attr:`__traceback__` attribute, which is writable.
|
||||
and attached to it as the :attr:`~BaseException.__traceback__` attribute.
|
||||
You can create an exception and set your own traceback in one step using the
|
||||
:meth:`~BaseException.with_traceback` exception method (which returns the
|
||||
same exception instance, with its traceback set to its argument), like so::
|
||||
|
@ -592,11 +592,13 @@ same exception instance, with its traceback set to its argument), like so::
|
|||
The ``from`` clause is used for exception chaining: if given, the second
|
||||
*expression* must be another exception class or instance. If the second
|
||||
expression is an exception instance, it will be attached to the raised
|
||||
exception as the :attr:`__cause__` attribute (which is writable). If the
|
||||
exception as the :attr:`~BaseException.__cause__` attribute (which is writable). If the
|
||||
expression is an exception class, the class will be instantiated and the
|
||||
resulting exception instance will be attached to the raised exception as the
|
||||
:attr:`__cause__` attribute. If the raised exception is not handled, both
|
||||
exceptions will be printed::
|
||||
:attr:`!__cause__` attribute. If the raised exception is not handled, both
|
||||
exceptions will be printed:
|
||||
|
||||
.. code-block:: pycon
|
||||
|
||||
>>> try:
|
||||
... print(1 / 0)
|
||||
|
@ -605,19 +607,24 @@ exceptions will be printed::
|
|||
...
|
||||
Traceback (most recent call last):
|
||||
File "<stdin>", line 2, in <module>
|
||||
print(1 / 0)
|
||||
~~^~~
|
||||
ZeroDivisionError: division by zero
|
||||
|
||||
The above exception was the direct cause of the following exception:
|
||||
|
||||
Traceback (most recent call last):
|
||||
File "<stdin>", line 4, in <module>
|
||||
raise RuntimeError("Something bad happened") from exc
|
||||
RuntimeError: Something bad happened
|
||||
|
||||
A similar mechanism works implicitly if a new exception is raised when
|
||||
an exception is already being handled. An exception may be handled
|
||||
when an :keyword:`except` or :keyword:`finally` clause, or a
|
||||
:keyword:`with` statement, is used. The previous exception is then
|
||||
attached as the new exception's :attr:`__context__` attribute::
|
||||
attached as the new exception's :attr:`~BaseException.__context__` attribute:
|
||||
|
||||
.. code-block:: pycon
|
||||
|
||||
>>> try:
|
||||
... print(1 / 0)
|
||||
|
@ -626,16 +633,21 @@ attached as the new exception's :attr:`__context__` attribute::
|
|||
...
|
||||
Traceback (most recent call last):
|
||||
File "<stdin>", line 2, in <module>
|
||||
print(1 / 0)
|
||||
~~^~~
|
||||
ZeroDivisionError: division by zero
|
||||
|
||||
During handling of the above exception, another exception occurred:
|
||||
|
||||
Traceback (most recent call last):
|
||||
File "<stdin>", line 4, in <module>
|
||||
raise RuntimeError("Something bad happened")
|
||||
RuntimeError: Something bad happened
|
||||
|
||||
Exception chaining can be explicitly suppressed by specifying :const:`None` in
|
||||
the ``from`` clause::
|
||||
the ``from`` clause:
|
||||
|
||||
.. doctest::
|
||||
|
||||
>>> try:
|
||||
... print(1 / 0)
|
||||
|
@ -653,8 +665,8 @@ and information about handling exceptions is in section :ref:`try`.
|
|||
:const:`None` is now permitted as ``Y`` in ``raise X from Y``.
|
||||
|
||||
.. versionadded:: 3.3
|
||||
The ``__suppress_context__`` attribute to suppress automatic display of the
|
||||
exception context.
|
||||
The :attr:`~BaseException.__suppress_context__` attribute to suppress
|
||||
automatic display of the exception context.
|
||||
|
||||
.. versionchanged:: 3.11
|
||||
If the traceback of the active exception is modified in an :keyword:`except`
|
||||
|
|
|
@ -711,7 +711,7 @@ new powerful features added:
|
|||
{Exception}({args})` instead of :samp:`raise {Exception}, {args}`.
|
||||
Additionally, you can no longer explicitly specify a traceback;
|
||||
instead, if you *have* to do this, you can assign directly to the
|
||||
:attr:`__traceback__` attribute (see below).
|
||||
:attr:`~BaseException.__traceback__` attribute (see below).
|
||||
|
||||
* :pep:`3110`: Catching exceptions. You must now use
|
||||
:samp:`except {SomeException} as {variable}` instead
|
||||
|
@ -725,7 +725,7 @@ new powerful features added:
|
|||
handler block. This usually happens due to a bug in the handler
|
||||
block; we call this a *secondary* exception. In this case, the
|
||||
original exception (that was being handled) is saved as the
|
||||
:attr:`__context__` attribute of the secondary exception.
|
||||
:attr:`~BaseException.__context__` attribute of the secondary exception.
|
||||
Explicit chaining is invoked with this syntax::
|
||||
|
||||
raise SecondaryException() from primary_exception
|
||||
|
@ -733,14 +733,15 @@ new powerful features added:
|
|||
(where *primary_exception* is any expression that produces an
|
||||
exception object, probably an exception that was previously caught).
|
||||
In this case, the primary exception is stored on the
|
||||
:attr:`__cause__` attribute of the secondary exception. The
|
||||
:attr:`~BaseException.__cause__` attribute of the secondary exception. The
|
||||
traceback printed when an unhandled exception occurs walks the chain
|
||||
of :attr:`__cause__` and :attr:`__context__` attributes and prints a
|
||||
of :attr:`!__cause__` and :attr:`~BaseException.__context__` attributes and
|
||||
prints a
|
||||
separate traceback for each component of the chain, with the primary
|
||||
exception at the top. (Java users may recognize this behavior.)
|
||||
|
||||
* :pep:`3134`: Exception objects now store their traceback as the
|
||||
:attr:`__traceback__` attribute. This means that an exception
|
||||
:attr:`~BaseException.__traceback__` attribute. This means that an exception
|
||||
object now contains all the information pertaining to an exception,
|
||||
and there are fewer reasons to use :func:`sys.exc_info` (though the
|
||||
latter is not removed).
|
||||
|
|
Loading…
Reference in New Issue