rspec/rules/S5709/python/rule.adoc

60 lines
2.3 KiB
Plaintext
Raw Normal View History

2023-08-04 16:45:15 +02:00
This rule raises an issue when a class derives from one of the following exception classes: ``++BaseException++``, ``++KeyboardInterrupt++``, ``++SystemExit++`` or ``++GeneratorExit++``.
2021-04-28 16:49:39 +02:00
2023-08-04 16:45:15 +02:00
== Why is this an issue?
2021-04-28 16:49:39 +02:00
2023-08-04 16:45:15 +02:00
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.
2021-04-28 16:49:39 +02:00
2023-08-04 16:45:15 +02:00
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.
2021-04-28 16:49:39 +02:00
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.
2023-08-04 16:45:15 +02:00
=== Code examples
2021-04-28 16:49:39 +02:00
2023-08-04 16:45:15 +02:00
==== Noncompliant code example
2021-04-28 16:49:39 +02:00
2023-08-04 16:45:15 +02:00
[source,python,diff-id=1,diff-type=noncompliant]
2021-04-28 16:49:39 +02:00
----
class MyException(BaseException): # Noncompliant
pass
----
2023-08-04 16:45:15 +02:00
==== Compliant solution
2023-08-04 16:45:15 +02:00
[source,python,diff-id=1,diff-type=compliant]
2021-04-28 16:49:39 +02:00
----
class MyException(Exception):
pass
----
== Resources
2021-04-28 16:49:39 +02:00
2023-08-04 16:45:15 +02:00
=== Documentation
2021-04-28 16:49:39 +02:00
* 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.
2023-08-04 16:45:15 +02:00
[source,text]
----
class Foo(BaseException)
2023-08-04 16:45:15 +02:00
^^^^^^^^^^^^^
----
endif::env-github,rspecator-view[]