rspec/rules/S5709/python/rule.adoc
2023-08-04 16:45:15 +02:00

60 lines
2.3 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This rule raises an issue when a class derives from one of the following exception classes: ``++BaseException++``, ``++KeyboardInterrupt++``, ``++SystemExit++`` or ``++GeneratorExit++``.
== Why is this an issue?
https://docs.python.org/3/library/exceptions.html#SystemExit[``++SystemExit++``] is raised when https://docs.python.org/3/library/sys.html#sys.exit[``++sys.exit()++``] is called. https://docs.python.org/3/library/exceptions.html#KeyboardInterrupt[``++KeyboardInterrupt++``] is raised when the user asks the program to stop by pressing interrupt keys. Both exceptions are expected to propagate up until the application stops.
In order to avoid catching ``++SystemExit++`` and ``++KeyboardInterrupt++`` by mistake, https://www.python.org/dev/peps/pep-0352/#exception-hierarchy[PEP-352] created the root class ``++BaseException++`` from which ``++SystemExit++``, ``++KeyboardInterrupt++`` and ``++Exception++`` derive. Thus developers can use ``++except Exception:++`` without preventing the software from stopping.
The ``++GeneratorExit++`` class also derives from ``++BaseException++`` as it is not really an error and is not supposed to be caught by user code.
As said in https://docs.python.org/3/library/exceptions.html#BaseException[Python's documentation], user-defined exceptions are not supposed to inherit directly from ``++BaseException++``. They should instead inherit from ``++Exception++`` or one of its subclasses.
=== Code examples
==== Noncompliant code example
[source,python,diff-id=1,diff-type=noncompliant]
----
class MyException(BaseException): # Noncompliant
pass
----
==== Compliant solution
[source,python,diff-id=1,diff-type=compliant]
----
class MyException(Exception):
pass
----
== Resources
=== Documentation
* 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#BaseException[BaseException class]
ifdef::env-github,rspecator-view[]
'''
== Implementation Specification
(visible only on this page)
=== Message
Derive this class from "Exception" instead of BaseException/GeneratorExit/KeyboardInterrupt/SystemExit
=== Highlighting
The forbidden parent class reference.
[source,text]
----
class Foo(BaseException)
^^^^^^^^^^^^^
----
endif::env-github,rspecator-view[]