Skip to content

Commit 0f14f79

Browse files
authored
SONARPY-1325 Fix FP on S5727 when annotated return type is object (#1465)
1 parent 66323c2 commit 0f14f79

File tree

3 files changed

+25
-2
lines changed

3 files changed

+25
-2
lines changed

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

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,8 @@ private static void checkEqualityComparison(SubscriptionContext ctx, BinaryExpre
5757
private static void checkIdentityComparison(SubscriptionContext ctx, IsExpression comparison) {
5858
InferredType left = comparison.leftOperand().type();
5959
InferredType right = comparison.rightOperand().type();
60-
if (!left.isIdentityComparableWith(right) && (isNone(left) || isNone(right))) {
60+
// `isObject` Removes FP when the return type of a function is an object
61+
if (!left.isIdentityComparableWith(right) && (isNone(left) || isNone(right)) && !(isObject(left) || isObject(right))) {
6162
addIssue(ctx, comparison, "identity check", comparison.notToken() != null);
6263
} else if (isNone(left) && isNone(right)) {
6364
addIssue(ctx, comparison, "identity check", comparison.notToken() == null);
@@ -70,6 +71,11 @@ private static void addIssue(SubscriptionContext ctx, Tree tree, String comparis
7071
}
7172

7273
private static boolean cannotBeNone(InferredType type) {
73-
return !type.canBeOrExtend(BuiltinTypes.NONE_TYPE);
74+
return !type.canBeOrExtend(BuiltinTypes.NONE_TYPE) && !isObject(type);
7475
}
76+
77+
private static boolean isObject(InferredType type) {
78+
return type.canOnlyBe(BuiltinTypes.OBJECT_TYPE);
79+
}
80+
7581
}

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

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import pydoc
12
def identity_check(param):
23
a = None
34
b = 42
@@ -13,6 +14,13 @@ def identity_check(param):
1314
if b is d: pass
1415
if None is a: pass # Noncompliant
1516
if None is b: pass # Noncompliant
17+
obj = pydoc.locate("test")
18+
if obj is not None: pass
19+
if None is not obj: pass
20+
21+
obj = object()
22+
if obj is not None: pass # FN
23+
if None is obj: pass # FN
1624

1725
def equality_check(param):
1826
a = None
@@ -30,3 +38,10 @@ def equality_check(param):
3038
d = "abc"
3139
if b == d: pass
3240
if b != d: pass
41+
obj = pydoc.locate("test")
42+
if obj == None: pass
43+
if None == obj: pass
44+
45+
obj = object()
46+
if obj == None: pass # FN
47+
if None == obj: pass # FN

python-frontend/src/main/java/org/sonar/plugins/python/api/types/BuiltinTypes.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ public class BuiltinTypes {
3434
public static final String EXCEPTION = "Exception";
3535
public static final String BASE_EXCEPTION = "BaseException";
3636

37+
public static final String OBJECT_TYPE = "object";
38+
3739
private BuiltinTypes() {
3840
}
3941

0 commit comments

Comments
 (0)