rspec/rules/S5707/python/rule.adoc

64 lines
1.9 KiB
Plaintext
Raw Normal View History

2021-04-28 16:49:39 +02:00
Exception chaining enables users to see if an exception was triggered by another exception (see https://www.python.org/dev/peps/pep-3134/[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 https://www.python.org/dev/peps/pep-0409/[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.
== Noncompliant Code Example
----
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
----
== Compliant Solution
----
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
----
== See
* PEP 3134 https://www.python.org/dev/peps/pep-3134/[Exception Chaining and Embedded Tracebacks]
* PEP 409 https://www.python.org/dev/peps/pep-0409/[Suppressing exception context]
* PEP 352 - https://www.python.org/dev/peps/pep-0352/#exception-hierarchy-changes[Required Superclass for Exceptions]
* Python documentation - https://docs.python.org/3/library/exceptions.html[Built-in Exceptions]