Skip to content

Commit 1802adf

Browse files
SONARPY-997 Fix FP on S5632 for nonlocal variables (#1116)
1 parent 111c458 commit 1802adf

File tree

2 files changed

+22
-4
lines changed

2 files changed

+22
-4
lines changed

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

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -46,16 +46,19 @@ public void initialize(Context context) {
4646
return;
4747
}
4848
Expression raisedExpression = raiseStatement.expressions().get(0);
49-
if (!raisedExpression.type().canBeOrExtend(BASE_EXCEPTION)) {
50-
ctx.addIssue(raiseStatement, MESSAGE);
51-
return;
52-
}
5349
Symbol symbol = null;
5450
if (raisedExpression instanceof HasSymbol) {
5551
symbol = ((HasSymbol) raisedExpression).symbol();
5652
} else if (raisedExpression.is(Tree.Kind.CALL_EXPR)) {
5753
symbol = ((CallExpression) raisedExpression).calleeSymbol();
5854
}
55+
if (hasGlobalOrNonLocalUsage(symbol)) {
56+
return;
57+
}
58+
if (!raisedExpression.type().canBeOrExtend(BASE_EXCEPTION)) {
59+
ctx.addIssue(raiseStatement, MESSAGE);
60+
return;
61+
}
5962
if (!mayInheritFromBaseException(symbol)) {
6063
ctx.addIssue(raiseStatement, MESSAGE);
6164
}
@@ -77,4 +80,8 @@ private static boolean mayInheritFromBaseException(@Nullable Symbol symbol) {
7780
// to handle other builtins like 'NotImplemented'
7881
return !BuiltinSymbols.all().contains(symbol.fullyQualifiedName());
7982
}
83+
84+
private static boolean hasGlobalOrNonLocalUsage(@Nullable Symbol symbol) {
85+
return symbol != null && symbol.usages().stream().anyMatch(s -> s.tree().parent().is(Tree.Kind.GLOBAL_STMT, Tree.Kind.NONLOCAL_STMT));
86+
}
8087
}

python-checks/src/test/resources/checks/incorrectExceptionType/incorrectExceptionType.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,3 +142,14 @@ def raise_with_str_concat():
142142

143143
def raise_builtin_exception_with_fqn_null():
144144
raise IOError()
145+
146+
147+
def no_fp_on_nonlocal_variables(x):
148+
exception = None
149+
def do_something():
150+
nonlocal exception
151+
if foo():
152+
exception = ValueError("Hello")
153+
do_something()
154+
if exception:
155+
raise exception

0 commit comments

Comments
 (0)