PEP: 415 Title: Implement context suppression with exception attributes
Version: $Revision$ Last-Modified: $Date$ Author: Benjamin Peterson
<benjamin@python.org> BDFL-Delegate: Nick Coghlan Status: Final Type:
Standards Track Content-Type: text/x-rst Created: 26-Feb-2012
Python-Version: 3.3 Post-History: 26-Feb-2012 Replaces: 409 Resolution:
https://mail.python.org/pipermail/python-dev/2012-May/119467.html

Abstract
========

PEP 409 introduced support for the `raise exc from None` construct to
allow the display of the exception context to be explicitly suppressed.
This PEP retains the language level changes already implemented in PEP
409, but replaces the underlying implementation mechanism with a simpler
approach based on a new `__suppress_context__` attribute on all
`BaseException` instances.

PEP Acceptance
==============

This PEP was accepted by Nick Coghlan on the 14th of May, 2012.

Rationale
=========

PEP 409 changes `__cause__` to be `Ellipsis` by default. Then if
`__cause__` is set to `None` by `raise exc from None`, no context or
cause will be printed should the exception be uncaught.

The main problem with this scheme is it complicates the role of
`__cause__`. `__cause__` should indicate the cause of the exception not
whether `__context__` should be printed or not. This use of `__cause__`
is also not easily extended in the future. For example, we may someday
want to allow the programmer to select which of `__context__` and
`__cause__` will be printed. The PEP 409 implementation is not amenable
to this.

The use of `Ellipsis` is a hack. Before PEP 409, `Ellipsis` was used
exclusively in extended slicing. Extended slicing has nothing to do with
exceptions, so it's not clear to someone inspecting an exception object
why `__cause__` should be set to `Ellipsis`. Using `Ellipsis` by default
for `__cause__` makes it asymmetrical with `__context__`.

Proposal
========

A new attribute on `BaseException`, `__suppress_context__`, will be
introduced. Whenever `__cause__` is set, `__suppress_context__` will be
set to `True`. In particular, `raise exc from cause` syntax will set
`exc.__suppress_context__` to `True`. Exception printing code will check
for that attribute to determine whether context and cause will be
printed. `__cause__` will return to its original purpose and values.

There is precedence for `__suppress_context__` with the
`print_line_and_file` exception attribute.

To summarize, `raise exc from cause` will be equivalent to::

    exc.__cause__ = cause
    raise exc

where `exc.__cause__ = cause` implicitly sets
`exc.__suppress_context__`.

Patches
=======

There is a patch on `Issue 14133`\_.

References
==========

.. \_issue 14133: http://bugs.python.org/issue14133

Copyright
=========

This document has been placed in the public domain.

 .. Local Variables: mode: indented-text indent-tabs-mode: nil
sentence-end-double-space: t fill-column: 70 coding: utf-8 End:
