Skip to content

Commit 30577a8

Browse files
Update rules metadata (#1504)
1 parent 94d7b8c commit 30577a8

38 files changed

+1302
-659
lines changed
Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,18 @@
1+
<p>This rule raises an issue when a pre/post increment or decrement operator is used.</p>
12
<h2>Why is this an issue?</h2>
23
<p>Python has no pre/post increment/decrement operator. For instance, <code>x++</code> and <code>x--</code> will fail to parse. More importantly,
34
<code>++x</code> and <code>--x</code> will do nothing. To increment a number, simply write <code>x += 1</code>.</p>
4-
<h3>Noncompliant code example</h3>
5-
<pre>
6-
++x # Noncompliant
5+
<h3>Code examples</h3>
6+
<h4>Noncompliant code example</h4>
7+
<pre data-diff-id="1" data-diff-type="noncompliant">
8+
++x # Noncompliant: pre and post increment operators do not exist in Python.
9+
10+
x-- # Noncompliant: pre and post decrement operators do not exist in Python.
711
</pre>
8-
<h3>Compliant solution</h3>
9-
<pre>
12+
<h4>Compliant solution</h4>
13+
<pre data-diff-id="1" data-diff-type="compliant">
1014
x += 1
15+
16+
x -= 1
1117
</pre>
1218

Lines changed: 31 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,43 +1,54 @@
1+
<p>This rule raises an issue when an <code>except</code> statement has had all its exceptions caught by a previous <code>except</code> clause.</p>
12
<h2>Why is this an issue?</h2>
2-
<p>Exceptions handlers (<code>except:</code>) are evaluated in the order they are written. Once a match is found, the evaluation stops.</p>
3-
<p>In some contexts an except block is dead code as it will never catch any exception:</p>
3+
<p>Exceptions handlers (<code>except</code>) are evaluated in the order they are written. Once a match is found, the evaluation stops.</p>
4+
<p>In some contexts, an except block is dead code as it will never catch any exception:</p>
45
<ul>
56
<li> If there is a handler for a base class followed by a handler for class derived from that base class, the second handler will never trigger: The
67
handler for the base class will match the derived class, and will be the only executed handler. </li>
78
<li> When multiple <code>except</code> statements try to catch the same exception class, only the first one will be executed. </li>
8-
<li> In python 3, <code>BaseException</code> is the parent of every exception class. When <code>BaseException</code> is caught and the same
9-
try-except block has a bare <code>except:</code> statement, i.e. an <code>except</code> with no expression, the bare except will never catch
10-
anything. </li>
9+
<li> In Python 3, <code>BaseException</code> is the parent of every exception class. When a <code>BaseException</code> is caught by an
10+
<code>except</code> clause, none of the subsequent <code>except</code> statement will catch anything. This is true as well for the bare except
11+
statement (<code>except:</code>). </li>
1112
</ul>
12-
<p>This rule raises an issue when an <code>except</code> block catches every exception before a later <code>except</code> block could catch it.</p>
13-
<h3>Noncompliant code example</h3>
14-
<pre>
13+
<h2>How to fix it</h2>
14+
<p>When using multiple <code>except</code> statements, make sure to:</p>
15+
<ul>
16+
<li> Order the <code>except</code> blocks from the most specialzed exception to the most generic, i.e when wanting to catch a
17+
<code>FloatingPointError</code> and an <code>ArithemticError</code>, as <code>FloatingPointError</code> is a subclass of
18+
<code>ArithmeticError</code>, the first <code>except</code> statement should be <code>FloatingPointError</code>. </li>
19+
<li> Catch the same exception only once. </li>
20+
<li> Catch a <code>BaseException</code> only once with either an <code>except BaseException:</code> statement or a bare <code>except:</code>
21+
statement, as the two statements are equivalent. </li>
22+
</ul>
23+
<h3>Code examples</h3>
24+
<h4>Noncompliant code example</h4>
25+
<pre data-diff-id="1" data-diff-type="noncompliant">
1526
def foo():
1627
try:
1728
raise FloatingPointError()
1829
except (ArithmeticError, RuntimeError) as e:
1930
print(e)
20-
except FloatingPointError as e: # Noncompliant. FloatingPointError is a subclass of ArithmeticError
31+
except FloatingPointError as e: # Noncompliant: FloatingPointError is a subclass of ArithmeticError.
2132
print("Never executed")
22-
except OverflowError as e: # Noncompliant. OverflowError is a subclass of ArithmeticError
33+
except OverflowError as e: # Noncompliant: OverflowError is a subclass of ArithmeticError.
2334
print("Never executed")
2435

2536
try:
2637
raise TypeError()
2738
except TypeError as e:
2839
print(e)
29-
except TypeError as e: # Noncompliant. Duplicate Except.
40+
except TypeError as e: # Noncompliant: duplicate except.
3041
print("Never executed")
3142

3243
try:
3344
raise ValueError()
3445
except BaseException as e:
3546
print(e)
36-
except: # Noncompliant. This is equivalent to "except BaseException" block
47+
except: # Noncompliant: this is equivalent to "except BaseException" block.
3748
print("Never executed")
3849
</pre>
39-
<h3>Compliant solution</h3>
40-
<pre>
50+
<h4>Compliant solution</h4>
51+
<pre data-diff-id="1" data-diff-type="compliant">
4152
def foo():
4253
try:
4354
raise FloatingPointError()
@@ -58,9 +69,13 @@ <h3>Compliant solution</h3>
5869
except BaseException as e:
5970
print(e)
6071
</pre>
72+
<p><strong>Note</strong>: <em>It is generally not recommended to try catching <code>BaseException</code>, as it is the base class for all built-in
73+
exceptions in Python, including system-exiting exceptions like <code>SystemExit</code> or <code>KeyboardInterrupt</code>, which are typically not
74+
meant to be caught. See <a href="https://www.python.org/dev/peps/pep-0352/#exception-hierarchy-changes">PEP 352</a> for more information.</em></p>
6175
<h2>Resources</h2>
76+
<h3>Documentation</h3>
6277
<ul>
63-
<li> Python Documentation - <a href="https://docs.python.org/3/reference/compound_stmts.html#the-try-statement">The <code>try</code> statement</a>
64-
</li>
78+
<li> <a href="https://docs.python.org/3/reference/compound_stmts.html#the-try-statement">The <code>try</code> statement</a> </li>
79+
<li> <a href="https://docs.python.org/3/library/exceptions.html#exception-hierarchy">Exception hierarchy</a> </li>
6580
</ul>
6681

python-checks/src/main/resources/org/sonar/l10n/py/rules/python/S108.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ <h2>Why is this an issue?</h2>
66
for i in range(3):
77
pass
88
</pre>
9-
<p>Removing or filling the empty code blocks takes away ambiguity and generally results in a more straightforward and less surprising code. ===
10-
Exceptions</p>
9+
<p>Removing or filling the empty code blocks takes away ambiguity and generally results in a more straightforward and less surprising code.</p>
10+
<h3>Exceptions</h3>
1111
<p>The rule ignores code blocks that contain comments.</p>
1212

Lines changed: 40 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,48 @@
1+
<p>This rule raises an issue when a <code>break</code> or <code>continue</code> statement is used outside of a loop.</p>
12
<h2>Why is this an issue?</h2>
2-
<p><code>break</code> and <code>continue</code> are unstructured control flow statements which make code harder to read. Additionally, more recent
3-
versions of Python raise a SyntaxError when modules containing <code>break</code> or <code>continue</code> outside of a loop are imported.</p>
4-
<p>Therefore, these statements should not be used outside of loops.</p>
5-
<h3>Noncompliant code example</h3>
3+
<p><code>break</code> and <code>continue</code> are control flow statements used inside of loops. <code>break</code> is used to break out of its
4+
innermost enclosing loop and <code>continue</code> will continue with the next iteration.</p>
5+
<p>The example below illustrates the use of <code>break</code> in a <code>while</code> loop:</p>
66
<pre>
7+
n = 1
8+
while n &lt; 10:
9+
if n % 3 == 0:
10+
print("Found a number divisible by 3", n)
11+
break
12+
n = n + 1
13+
</pre>
14+
<p>This next example uses <code>continue</code> inside a <code>for</code> loop:</p>
15+
<pre>
16+
words = ["alice", "bob", "charlie"]
17+
for word in words:
18+
if word == word[::-1]:
19+
print("Found a palindrome", word)
20+
continue
21+
print("This is not a palindrome", word)
22+
</pre>
23+
<p>Python will raise a <code>SyntaxError</code> when <code>break</code> or <code>continue</code> are used outside of <code>for</code> or
24+
<code>while</code> loops.</p>
25+
<p>If the goal is to interrupt the main program flow, <code>quit()</code>, <code>exit()</code>, <code>os._exit()</code> and <code>sys.exit()</code>
26+
are the preferred way.</p>
27+
<h3>Code examples</h3>
28+
<h4>Noncompliant code example</h4>
29+
<pre data-diff-id="1" data-diff-type="noncompliant">
730
narg=len(sys.argv)
831
if narg == 1:
9-
print('@Usage: input_filename nelements nintervals')
10-
break
32+
print('@Usage: input_filename nelements nintervals')
33+
break
1134
</pre>
12-
<h3>Compliant solution</h3>
13-
<pre>
35+
<h4>Compliant solution</h4>
36+
<pre data-diff-id="1" data-diff-type="compliant">
37+
narg=len(sys.argv)
1438
if narg == 1:
15-
print('@Usage: input_filename nelements nintervals')
16-
sys.exit()
39+
print('@Usage: input_filename nelements nintervals')
40+
sys.exit()
1741
</pre>
42+
<h2>Resources</h2>
43+
<h3>Documentation</h3>
44+
<ul>
45+
<li> <a href="https://docs.python.org/3/tutorial/controlflow.html#break-and-continue-statements-and-else-clauses-on-loops">break and continue
46+
Statements</a> </li>
47+
</ul>
1848

Lines changed: 34 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,38 @@
1+
<p>This rule raises an issue when <code>return</code> or <code>yield</code> are used outside of a function.</p>
12
<h2>Why is this an issue?</h2>
23
<p><code>yield</code> and <code>return</code> only make sense in the context of functions. Using them outside a function raises a
3-
<code>SyntaxError</code>. To break out of a loop, use <code>break</code> instead.</p>
4-
<h3>Noncompliant code example</h3>
5-
<pre>
6-
class MyClass:
7-
while True:
8-
return False #Noncompliant
4+
<code>SyntaxError</code>.</p>
5+
<p>If the goal is to break out of a loop, use <code>break</code> instead of <code>return</code>.</p>
6+
<h3>Code examples</h3>
7+
<h4>Noncompliant code example</h4>
8+
<pre data-diff-id="1" data-diff-type="noncompliant">
9+
a = 1
10+
while a &lt; 3:
11+
if a % 2 == 0:
12+
return # Noncompliant: return is outside of a function
13+
a += 1
14+
15+
for n in range(5):
16+
yield n # Noncompliant: yield is outside of a function
17+
</pre>
18+
<h4>Compliant solution</h4>
19+
<pre data-diff-id="1" data-diff-type="compliant">
20+
a = 1
21+
while a &lt; 3:
22+
if a % 2 == 0:
23+
break
24+
a += 1
25+
26+
def gen():
27+
for n in range(5):
28+
yield n
929
</pre>
30+
<h2>Resources</h2>
31+
<h3>Documentation</h3>
32+
<ul>
33+
<li> Python Documentation - <a href="https://docs.python.org/3/reference/expressions.html?highlight=yield#yield-expressions">Yield expressions</a>
34+
</li>
35+
<li> Python Documentation - <a href="https://docs.python.org/3/reference/simple_stmts.html?highlight=return%20tatement#the-return-statement">Return
36+
statement</a> </li>
37+
</ul>
1038

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,28 @@
1+
<p>This rule raises an issue when the <code>__init__</code> method of a class contains a <code>return</code> or a <code>yield</code> statement.</p>
12
<h2>Why is this an issue?</h2>
2-
<p>By contract, every Python function returns something, even if it’s the <code>None</code> value, which can be returned implicitly by omitting the
3+
<p>By contract, every Python function returns something, even if it is the <code>None</code> value, which can be returned implicitly by omitting the
34
<code>return</code> statement, or explicitly.</p>
45
<p>The <code>__init__</code> method is required to return <code>None</code>. A <code>TypeError</code> will be raised if the <code>__init__</code>
5-
method either <code>yield</code>s or <code>return</code>s any expression other than <code>None</code>. Returning some expression that evaluates to
6-
<code>None</code> will not raise an error, but is considered bad practice.</p>
7-
<h3>Noncompliant code example</h3>
8-
<pre>
6+
method either yields or returns any expression other than <code>None</code>. While explicitly returning an expression that evaluates to
7+
<code>None</code> will not raise an error, it is considered bad practice.</p>
8+
<p>To fix this issue, make sure that the <code>__init__</code> method does not contain any return statement.</p>
9+
<h3>Code examples</h3>
10+
<h4>Noncompliant code example</h4>
11+
<pre data-diff-id="1" data-diff-type="noncompliant">
912
class MyClass(object):
1013
def __init__(self):
1114
self.message = 'Hello'
12-
return self # Noncompliant
15+
return self # Noncompliant: a TypeError will be raised
1316
</pre>
14-
<h3>Compliant solution</h3>
15-
<pre>
17+
<h4>Compliant solution</h4>
18+
<pre data-diff-id="1" data-diff-type="compliant">
1619
class MyClass(object):
1720
def __init__(self):
1821
self.message = 'Hello'
1922
</pre>
23+
<h2>Resources</h2>
24+
<h3>Documentation</h3>
25+
<ul>
26+
<li> <a href="https://docs.python.org/3/reference/datamodel.html#object.__init__">The <code>__init__</code> method</a> </li>
27+
</ul>
2028

python-checks/src/main/resources/org/sonar/l10n/py/rules/python/S2737.html

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,14 @@
11
<h2>Why is this an issue?</h2>
22
<p>An <code>except</code> clause that only rethrows the caught exception has the same effect as omitting the <code>except</code> altogether and
3-
letting it bubble up automatically, but with more code and the additional detriment of leaving maintainers scratching their heads.</p>
4-
<p>Such clauses should either be eliminated or populated with the appropriate logic.</p>
5-
<h3>Noncompliant code example</h3>
3+
letting it bubble up automatically.</p>
64
<pre>
75
a = {}
86
try:
97
a[5]
108
except KeyError:
119
raise # Noncompliant
1210
</pre>
13-
<h3>Compliant solution</h3>
11+
<p>Such clauses should either be removed or populated with the appropriate logic.</p>
1412
<pre>
1513
a = {}
1614
try:

0 commit comments

Comments
 (0)