Skip to content

Commit 3daca82

Browse files
committed
SONARPY-208 Rule: Unused local variables should be removed
1 parent da98dc7 commit 3daca82

10 files changed

Lines changed: 1117 additions & 1 deletion

File tree

its/ruling/src/test/resources/expected/python-S1481.json

Lines changed: 981 additions & 0 deletions
Large diffs are not rendered by default.

its/ruling/src/test/resources/profile.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,11 @@
170170
<key>S1313</key>
171171
<priority>INFO</priority>
172172
</rule>
173+
<rule>
174+
<repositoryKey>python</repositoryKey>
175+
<key>S1481</key>
176+
<priority>INFO</priority>
177+
</rule>
173178
<rule>
174179
<repositoryKey>python</repositoryKey>
175180
<key>S1578</key>

python-checks/src/main/java/org/sonar/python/checks/CheckList.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ public static Iterable<Class> getChecks() {
8181
DuplicatedMethodFieldNamesCheck.class,
8282
TooManyReturnsCheck.class,
8383
NeedlessPassCheck.class,
84+
UnusedLocalVariableCheck.class,
8485
AfterJumpStatementCheck.class,
8586
IdenticalExpressionOnBinaryOperatorCheck.class,
8687
SelfAssignmentCheck.class,
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
/*
2+
* SonarQube Python Plugin
3+
* Copyright (C) 2011-2017 SonarSource SA
4+
* mailto:info AT sonarsource DOT com
5+
*
6+
* This program is free software; you can redistribute it and/or
7+
* modify it under the terms of the GNU Lesser General Public
8+
* License as published by the Free Software Foundation; either
9+
* version 3 of the License, or (at your option) any later version.
10+
*
11+
* This program is distributed in the hope that it will be useful,
12+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14+
* Lesser General Public License for more details.
15+
*
16+
* You should have received a copy of the GNU Lesser General Public License
17+
* along with this program; if not, write to the Free Software Foundation,
18+
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19+
*/
20+
package org.sonar.python.checks;
21+
22+
import com.google.common.collect.ImmutableSet;
23+
import com.sonar.sslr.api.AstNode;
24+
import com.sonar.sslr.api.AstNodeType;
25+
import java.util.Set;
26+
import org.sonar.check.Rule;
27+
import org.sonar.python.PythonCheck;
28+
import org.sonar.python.api.PythonGrammar;
29+
import org.sonar.python.semantic.Symbol;
30+
31+
@Rule(key = "S1481")
32+
public class UnusedLocalVariableCheck extends PythonCheck {
33+
34+
private static final String MESSAGE = "Remove the unused local variable \"%s\".";
35+
36+
@Override
37+
public Set<AstNodeType> subscribedKinds() {
38+
return ImmutableSet.of(PythonGrammar.FUNCDEF);
39+
}
40+
41+
@Override
42+
public void visitNode(AstNode functionTree) {
43+
for (Symbol symbol : getContext().symbolTable().symbols(functionTree)) {
44+
checkSymbol(symbol);
45+
}
46+
}
47+
48+
private void checkSymbol(Symbol symbol) {
49+
if (symbol.readUsages().isEmpty()) {
50+
for (AstNode writeUsage : symbol.writeUsages()) {
51+
if (!writeUsage.hasAncestor(PythonGrammar.TYPEDARGSLIST)) {
52+
addIssue(writeUsage, String.format(MESSAGE, symbol.name()));
53+
}
54+
}
55+
}
56+
}
57+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<p>If a local variable is declared but not used, it is dead code and should be removed. Doing so will improve maintainability because developers will
2+
not wonder what the variable is used for.</p>
3+
<h2>Noncompliant Code Example</h2>
4+
<pre>
5+
def hello(name):
6+
message = "Hello " + name # Noncompliant
7+
print(name)
8+
</pre>
9+
<h2>Compliant Solution</h2>
10+
<pre>
11+
def hello(name):
12+
message = "Hello " + name
13+
print(message)
14+
</pre>
15+
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
{
2+
"title": "Unused local variables should be removed",
3+
"type": "CODE_SMELL",
4+
"status": "ready",
5+
"remediation": {
6+
"func": "Constant\/Issue",
7+
"constantCost": "5min"
8+
},
9+
"tags": [
10+
"unused"
11+
],
12+
"defaultSeverity": "Minor"
13+
}

python-checks/src/main/resources/org/sonar/l10n/py/rules/python/Sonar_way_profile.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
"S1110",
1818
"S1134",
1919
"S1313",
20+
"S1481",
2021
"S1542",
2122
"S1656",
2223
"S1700",
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
/*
2+
* SonarQube Python Plugin
3+
* Copyright (C) 2011-2017 SonarSource SA
4+
* mailto:info AT sonarsource DOT com
5+
*
6+
* This program is free software; you can redistribute it and/or
7+
* modify it under the terms of the GNU Lesser General Public
8+
* License as published by the Free Software Foundation; either
9+
* version 3 of the License, or (at your option) any later version.
10+
*
11+
* This program is distributed in the hope that it will be useful,
12+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14+
* Lesser General Public License for more details.
15+
*
16+
* You should have received a copy of the GNU Lesser General Public License
17+
* along with this program; if not, write to the Free Software Foundation,
18+
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19+
*/
20+
package org.sonar.python.checks;
21+
22+
import org.junit.Test;
23+
import org.sonar.python.checks.utils.PythonCheckVerifier;
24+
25+
public class UnusedLocalVariableCheckTest {
26+
27+
@Test
28+
public void test() {
29+
PythonCheckVerifier.verify("src/test/resources/checks/unusedLocalVariable.py", new UnusedLocalVariableCheck());
30+
}
31+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
unread_global = 1
2+
3+
def f(unread_param):
4+
global unread_global
5+
unread_global = 1
6+
unread_local = 1 # Noncompliant {{Remove the unused local variable "unread_local".}}
7+
unread_local = 2 # Noncompliant
8+
read_local = 1
9+
print(read_local)
10+
read_in_nested_function = 1
11+
def nested_function():
12+
print(read_in_nested_function)

sonar-python-plugin/src/test/java/org/sonar/plugins/python/PythonRuleRepositoryTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ public void createRulesTest() {
4242

4343
List<RulesDefinition.Rule> rules = repository.rules();
4444
assertThat(rules).isNotNull();
45-
assertThat(rules).hasSize(53);
45+
assertThat(rules).hasSize(54);
4646
}
4747

4848
}

0 commit comments

Comments
 (0)