Skip to content

Commit daefc87

Browse files
joke1196sonartech
authored andcommitted
SONARPY-3876 S1172 Fixing FPs on Django middleware conventional function parameters (#944)
GitOrigin-RevId: 47e0aba447a9b6095c644691b76dee20c18e39cb
1 parent 919dc81 commit daefc87

File tree

3 files changed

+57
-0
lines changed

3 files changed

+57
-0
lines changed

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

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@
4141
import org.sonar.plugins.python.api.tree.Token;
4242
import org.sonar.plugins.python.api.tree.Tree;
4343
import org.sonar.plugins.python.api.tree.Tree.Kind;
44+
import org.sonar.plugins.python.api.types.v2.matchers.TypeMatcher;
45+
import org.sonar.plugins.python.api.types.v2.matchers.TypeMatchers;
4446
import org.sonar.plugins.python.api.tree.Trivia;
4547
import org.sonar.python.checks.utils.CheckUtils;
4648
import org.sonar.python.checks.utils.StringLiteralValuesCollector;
@@ -57,6 +59,12 @@ public class UnusedFunctionParameterCheck extends PythonSubscriptionCheck {
5759

5860
private static final Set<String> AWS_LAMBDA_PARAMETERS = Set.of("event", "context");
5961

62+
private static final Set<String> DJANGO_MIDDLEWARE_METHODS = Set.of(
63+
"process_request", "process_exception", "process_view", "process_template_response");
64+
65+
private static final TypeMatcher MIDDLEWARE_MIXIN_MATCHER = TypeMatchers.isFunctionOwnerSatisfying(
66+
TypeMatchers.isOrExtendsType("django.utils.deprecation.MiddlewareMixin"));
67+
6068
@Override
6169
public void initialize(Context context) {
6270
context.registerSyntaxNodeConsumer(Kind.FUNCDEF, ctx -> checkFunctionParameter(ctx, ((FunctionDef) ctx.syntaxNode())));
@@ -119,6 +127,7 @@ private static boolean isException(SubscriptionContext ctx, FunctionDef function
119127
hasNonCallUsages(functionSymbol) ||
120128
isTestFunction(ctx, functionDef) ||
121129
isDjangoView(functionDef) ||
130+
isDjangoMiddlewareFunction(ctx, functionDef) ||
122131
isAbstractClass(functionDef);
123132
}
124133

@@ -201,4 +210,13 @@ private static boolean isDjangoView(FunctionDef functionDef) {
201210
FunctionSymbolImpl functionSymbolImpl = (FunctionSymbolImpl) functionSymbol;
202211
return functionSymbolImpl != null && functionSymbolImpl.isDjangoView();
203212
}
213+
214+
215+
private static boolean isDjangoMiddlewareFunction(SubscriptionContext ctx, FunctionDef functionDef) {
216+
String functionName = functionDef.name().name();
217+
if (!DJANGO_MIDDLEWARE_METHODS.contains(functionName)) {
218+
return false;
219+
}
220+
return MIDDLEWARE_MIXIN_MATCHER.isTrueFor(functionDef.name(), ctx);
221+
}
204222
}

python-checks/src/test/java/org/sonar/python/checks/UnusedFunctionParameterCheckTest.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,4 +57,11 @@ void test_django() {
5757
),
5858
new UnusedFunctionParameterCheck());
5959
}
60+
61+
@Test
62+
void test_django_middleware() {
63+
PythonCheckVerifier.verify(
64+
"src/test/resources/checks/unusedFunctionParameter/django/middleware.py",
65+
new UnusedFunctionParameterCheck());
66+
}
6067
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
from django.utils.deprecation import MiddlewareMixin
2+
3+
4+
class MyMiddleware(MiddlewareMixin):
5+
def process_request(self, request): # Compliant - Django middleware hook
6+
print("logging")
7+
8+
def process_exception(
9+
self, request, exception
10+
): # Compliant - Django middleware hook
11+
print("logging")
12+
13+
def process_view(
14+
self, request, view_func, view_args, view_kwargs
15+
): # Compliant - Django middleware hook
16+
print("logging")
17+
18+
def process_template_response(
19+
self, request, response
20+
): # Compliant - Django middleware hook
21+
print("logging")
22+
23+
def some_other_method(self, foo): # Noncompliant
24+
print("logging")
25+
26+
27+
class NotAMiddleware:
28+
def process_request(self, request): # Noncompliant
29+
print("logging")
30+
31+
def process_exception(self, request, exception): # Noncompliant 2
32+
print("logging")

0 commit comments

Comments
 (0)