]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
[3.12] gh-101100: Improve docs on exception attributes (GH-113057) (#113061)
authorMiss Islington (bot) <31488909+miss-islington@users.noreply.github.com>
Wed, 13 Dec 2023 19:07:19 +0000 (20:07 +0100)
committerGitHub <noreply@github.com>
Wed, 13 Dec 2023 19:07:19 +0000 (19:07 +0000)
gh-101100: Improve docs on exception attributes (GH-113057)

(cherry picked from commit d05a180350fe20d5fde56c7e525e394a0b282703)

Co-authored-by: Alex Waygood <Alex.Waygood@Gmail.com>
Doc/c-api/exceptions.rst
Doc/library/exceptions.rst
Doc/library/traceback.rst
Doc/reference/datamodel.rst
Doc/reference/simple_stmts.rst
Doc/whatsnew/3.0.rst

index f27e2bbfef05c59e5939a97a46e623dd40557bcc..d5119789a5f6233962003814f4a59df1ea0e090f 100644 (file)
@@ -528,7 +528,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::
 
@@ -740,7 +741,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``.
 
 
@@ -754,8 +756,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)
@@ -769,7 +771,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)
@@ -778,7 +781,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)
index 98972b476ba45f786ebc88b9290a493c87323c6f..6c898ce346db8bfa4437e65bbbc7a659beaecde9 100644 (file)
@@ -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.
-
-This implicit exception context can be
-supplemented with an explicit cause by using :keyword:`!from` with
-:keyword:`raise`::
-
-   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.
+.. index:: pair: exception; chaining
+           __cause__ (exception attribute)
+           __context__ (exception attribute)
+           __suppress_context__ (exception attribute)
+
+Three attributes on exception objects provide information about the context in
+which an the exception was raised:
+
+.. attribute:: BaseException.__context__
+               BaseException.__cause__
+               BaseException.__suppress_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.
+
+   This implicit exception context can be
+   supplemented with an explicit cause by using :keyword:`!from` with
+   :keyword:`raise`::
+
+      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
@@ -928,8 +946,10 @@ their subgroups based on the types of the contained exceptions.
       same check that is used in an ``except`` clause.
 
       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,
@@ -952,10 +972,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):
index d7baf04cee1d4a8710524367e83bd34a052afd39..12b8a27a59be09289381d9bde7ef7039f5238762 100644 (file)
@@ -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.
 
@@ -227,10 +228,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.
 
@@ -248,27 +250,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.
 
@@ -334,8 +340,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`
index 35d295ce139610826dde29ab14408171af95a89f..7609775de3bedd63043a5f4ab8fe78673da9d385 100644 (file)
@@ -1385,7 +1385,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
index a9e65be1eda34030755da4f8f768b913dec64c8f..34c3a620b87223fe81cfa2a4a005abf508d056da 100644 (file)
@@ -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`
index a44c52e8ebd3fc68e323758110e831320ff874b0..e1cd33377424450d25836c53fb1eb759bb150b18 100644 (file)
@@ -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).