Exception chaining enables users to see if an exception was triggered by another exception (see PEP-3134). Exceptions are chained using either of the following syntax:
* raise NewException() from chained_exception
* new_exception.__cause__ = chained_exception
It is also possible to erase a chaining by setting new_exception.__cause__ = None or using except ... from None (see PEP-409).
Chaining will fail and raise a TypeError if something else than None or a valid exception, i.e. an instance of
BaseException or of a subclass, is provided.
class A:
pass
try:
raise ValueError("orig")
except ValueError as e:
new_exc = TypeError("new")
new_exc.__cause__ = A() # Noncompliant
raise new_exc
try:
raise ValueError("orig")
except ValueError as e:
raise TypeError("new") from "test" # Noncompliant
try:
raise ValueError("orig")
except ValueError as e:
new_exc = TypeError("new")
new_exc.__cause__ = None # Ok
raise new_exc
try:
raise ValueError("orig")
except ValueError as e:
new_exc = TypeError("new")
new_exc.__cause__ = e # Ok
raise new_exc
try:
raise ValueError("orig")
except ValueError as e:
raise TypeError("new") from None # Ok
try:
raise ValueError("orig")
except ValueError as e:
raise TypeError("new") from e # Ok
* PEP 3134 – Exception Chaining and Embedded Tracebacks
* PEP 409 – Suppressing exception context
* PEP 352 - Required Superclass for Exceptions
* Python documentation - Built-in Exceptions