-
Notifications
You must be signed in to change notification settings - Fork 93
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
SONARPY-2332 Fix FP on S5845 when comparing enum objects with types #2170
Conversation
14a8153
to
e6cf96b
Compare
@@ -208,7 +207,7 @@ class DerivedEnumWithMembers(Enum): | |||
class ComparingTypeAndDerivedEnumWithMembers(unittest.TestCase): | |||
def test_type_of_derived_enum_and_derived_enum_class(self): | |||
derived_enum_member = DerivedEnumWithMembers(1) | |||
self.assertIs(type(enum_member), EnumType) | |||
self.assertIs(type(derived_enum_member), EnumType) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Mistake that was present in the previous ticket. I corrected it here.
aab7085
to
3d6f6f8
Compare
3d6f6f8
to
399db7e
Compare
@@ -31,6 +31,9 @@ | |||
|
|||
public class RuntimeType implements InferredType { | |||
|
|||
// Name of the type returned by the type() function | |||
private static final String TYPE_CLASS_NAME = "type"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Did you try to use org.sonar.python.types.InferredTypes#TYPE
?
It looks like that for the v1 type inference we have this constant representing the type
class.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
good catch, I ll use it. thanks
|
||
private static boolean hasMetaclassInHierarchy(RuntimeType runtimeType) { | ||
return runtimeType.getTypeClass().hasMetaClass() | ||
|| runtimeType.getTypeClass().superClasses().stream().filter(ClassSymbol.class::isInstance).anyMatch(c -> ((ClassSymbol) c).hasMetaClass()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should we look only for current type parents for a metaclass
, or should we go deeper in the types hierarchy?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I intend to go deeper as the original issue contained a child class from enum.Enum
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
as discussed - we need to check whole hierarchy, not nearest parents
if (other instanceof RuntimeType otherRuntimeType) { | ||
boolean hasOtherMetaClass = hasMetaclassInHierarchy(otherRuntimeType); | ||
boolean hasThisMetaClass = hasMetaclassInHierarchy(this); | ||
return (TYPE_CLASS_NAME.equals(getTypeClass().name()) && hasOtherMetaClass) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess there could be just a comparison with the org.sonar.python.types.InferredTypes#TYPE
constant.
@@ -52,9 +55,27 @@ public boolean isIdentityComparableWith(InferredType other) { | |||
if (other instanceof UnionType) { | |||
return other.isIdentityComparableWith(this); | |||
} | |||
if (isComparingTypeWithMetaclass(other)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should it be like this? maybe it will be cleaner to return:
return isComparingTypeWithMetaclass(other) || this.equals(other);
@@ -64,6 +64,34 @@ void isIdentityComparableWith() { | |||
assertThat(aType.isIdentityComparableWith(new DeclaredType(b))).isTrue(); | |||
} | |||
|
|||
@Test | |||
void isIdentityComparableWithMetaclass() { | |||
RuntimeType typeType = new RuntimeType(new ClassSymbolImpl("type", "type")); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
here you can use org.sonar.python.types.InferredTypes#TYPE
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good, I left some comments, seems that the implementation could be simplified
93f19e6
to
4b342a8
Compare
return isComparingTypeWithMetaclass(other) || this.equals(other); | ||
} | ||
|
||
private boolean isComparingTypeWithMetaclass(InferredType other) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
as discussed, could be simplified like this :
private boolean isComparingTypeWithMetaclass(InferredType other) {
if (other instanceof RuntimeType otherRuntimeType) {
boolean hasOtherMetaClass = hasMetaclassInHierarchy(otherRuntimeType);
boolean hasThisMetaClass = hasMetaclassInHierarchy(this);
return (InferredTypes.TYPE.equals(this) && hasOtherMetaClass)
|| (hasThisMetaClass && InferredTypes.TYPE.equals(otherRuntimeType));
}
return false;
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
After a discussion some changes requested
4b342a8
to
c50637d
Compare
Quality Gate passedIssues Measures |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, thanks for the fixes
SONARPY-2332
Part of