- Operating system: Windows 10
- SonarLint plugin version: Unclear, 3.30 is displayed under the title next to a star, 220.127.116.11884 is displayed next to the “Static Analysis” button without context, and change notes at the bottom lists a version 6.8 as the most recent with notes.
- Is connected mode used: Not specified, just installed via Pycharm, no configuration info available
- Connected to SonarCloud or SonarQube (and which version): are listed as options in the description, but no configuration settings are shown
And a thorough description of the problem:
Python docs refer to “exceptions” as a generic term for all exceptions, which are objects that derive from BaseException. It is confusing to break away from that and jump directly into the specific technical term “BaseException” which most users do not need to know except for the guideline to not use it. “BaseException” is used instead of “exception” to refer to exceptions generally, except when BaseException refers to the class
BaseException specifically. As a result, titles say things like “to be a class deriving from BaseException” (meaning the broad definition of an exception) while the rule says “do not use BaseException” (meaning the specific class) without any distinction between the two apparent contradictions. Instead, stick with the common python writing style and use
BaseException to refer to the class specifically, and use “exception” generally to refer to objects that derive from BaseException.
Option 1, find the description in SonarLint documentation:
Step 1: Go to this page: SonarSource Code Analyzers Rules Explorer
Step 1: create or use a class that is NOT an exception
Step 2: raise the object, e.g. with BuiltIns
raise int or
Step 3: Read the error and description in the SonarLint output tab.
Step 1: create or pick a class that is NOT an exception
Step 2: in a try/except block, catch the non-exception object, such as “except int” (note: non-callable instantiated objects, such as NotImplemented will not trigger any comments from SonarLint, despite not being defined as an exception)
Step 3: Read the error and description in the SonarLint console
SonarLint would report the error clearly:
Option 2 error: “Fix the raise call here to use an object defined as an exception.”
Option 3 error: “Change this expression to use an exception class or a tuple with only such classes.”
A clear definition of the problem needs to be in the first sentences of the description to support any error statements about resolving the issues. Such as:
“An object is being treated as an exception when it is not defined as one. All exceptions must derive from BaseException, which includes classes using Exception, the preferred base class for nearly all exceptions. In Python 3…” (existing writing continues)
Option 2 error: “Change this code so that it raises an object deriving from BaseException”
Option 3 error: “Change this expression to be a class deriving from BaseException or a tuple of such classes”
These descriptions are overly specific and technical, resulting in confusion. They imply a problem of inheritance, or even that “Exception” is not good enough for a user defined exception class, when the problem is the classes used simply are not proper exceptions of any derivation. If the user simply used an incorrect class they do not own, the derivation details are meaningless. If the user defined their own class, BaseException is specifically unimportant and not appropriate to headline the problem.
The description is worse, beginning with “In Python 3, attempting to catch…” which starts on a tangential discussion about on Python 3 vs 2 exception handling differences instead of the error, why it’s being reported, and what’s likely wrong. Backstory can come later. It’s not until the third paragraph before “Exception” is even mentioned; when it is, it sounds like a contradiction for anyone who hasn’t memorized PEP-0352 (which itself it not mentioned until the end of the paragraph) as the title says objects must inherit from BaseException and the details say do not do that.