File tree Expand file tree Collapse file tree 3 files changed +48
-3
lines changed
python-checks/src/test/resources/checks
main/java/org/sonar/python/types/v2
test/java/org/sonar/python/semantic/v2 Expand file tree Collapse file tree 3 files changed +48
-3
lines changed Original file line number Diff line number Diff line change @@ -84,8 +84,7 @@ class Factory: ...
84
84
class Base (metaclass = Factory ): ...
85
85
class A (Base ): ...
86
86
a = A ()
87
- # TODO: resolve type hierarchy and metaclasses
88
- a () # Noncompliant
87
+ a ()
89
88
90
89
91
90
def decorators ():
Original file line number Diff line number Diff line change @@ -148,7 +148,12 @@ public TriBool hasMember(String memberName) {
148
148
}
149
149
150
150
public boolean hasMetaClass () {
151
- return !this .metaClasses .isEmpty ();
151
+ return !this .metaClasses .isEmpty () ||
152
+ this .superClasses ()
153
+ .stream ()
154
+ .filter (ClassType .class ::isInstance )
155
+ .map (ClassType .class ::cast )
156
+ .anyMatch (ClassType ::hasMetaClass );
152
157
}
153
158
154
159
public TriBool instancesHaveMember (String memberName ) {
Original file line number Diff line number Diff line change @@ -1185,6 +1185,47 @@ def f():
1185
1185
.isEqualTo ("int" );
1186
1186
}
1187
1187
1188
+ @ Test
1189
+ void inferClassHierarchyHasMetaClass () {
1190
+ var root = inferTypes ("""
1191
+ class CustomMetaClass:
1192
+ ...
1193
+
1194
+ class ParentClass(metaclass=CustomMetaClass):
1195
+ ...
1196
+
1197
+ class ChildClass(ParentClass):
1198
+ ...
1199
+
1200
+ def f():
1201
+ a = ChildClass()
1202
+ a
1203
+ """ );
1204
+
1205
+
1206
+ var childClassType = TreeUtils .firstChild (root .statements ().statements ().get (2 ), ClassDef .class ::isInstance )
1207
+ .map (ClassDef .class ::cast )
1208
+ .map (ClassDef ::name )
1209
+ .map (Expression ::typeV2 )
1210
+ .map (ClassType .class ::cast )
1211
+ .get ();
1212
+
1213
+ Assertions .assertThat (childClassType .hasMetaClass ()).isTrue ();
1214
+
1215
+ var aType = TreeUtils .firstChild (root .statements ().statements ().get (3 ), ExpressionStatement .class ::isInstance )
1216
+ .map (ExpressionStatement .class ::cast )
1217
+ .flatMap (expressionStatement -> TreeUtils .firstChild (expressionStatement , Name .class ::isInstance ))
1218
+ .map (Name .class ::cast )
1219
+ .map (Expression ::typeV2 )
1220
+ .get ();
1221
+
1222
+ Assertions .assertThat (aType )
1223
+ .isNotNull ()
1224
+ .isNotEqualTo (PythonType .UNKNOWN )
1225
+ .extracting (PythonType ::unwrappedType )
1226
+ .isSameAs (childClassType );
1227
+ }
1228
+
1188
1229
private static FileInput inferTypes (String lines ) {
1189
1230
return inferTypes (lines , new HashMap <>());
1190
1231
}
You can’t perform that action at this time.
0 commit comments