Return null for the most derived class type if there is no total order among classes (PY-17841)

This commit is contained in:
Andrey Vlasovskikh
2015-12-11 18:54:04 +03:00
parent 616a5e3ce8
commit 938c84250c
3 changed files with 53 additions and 16 deletions
@@ -301,23 +301,31 @@ public class PyClassTypeImpl extends UserDataHolderBase implements PyClassType {
if (classTypes.isEmpty()) {
return null;
}
return Collections.max(classTypes, new Comparator<PyClassLikeType>() {
@Override
public int compare(@Nullable PyClassLikeType t1, @Nullable PyClassLikeType t2) {
if (t1 == t2 || t1 != null && t1.equals(t2)) {
return 0;
try {
return Collections.max(classTypes, new Comparator<PyClassLikeType>() {
@Override
public int compare(@Nullable PyClassLikeType t1, @Nullable PyClassLikeType t2) {
if (t1 == t2 || t1 != null && t1.equals(t2)) {
return 0;
}
else if (t2 == null || t1 != null && Sets.newHashSet(t1.getAncestorTypes(context)).contains(t2)) {
return 1;
}
else if (t1 == null || Sets.newHashSet(t2.getAncestorTypes(context)).contains(t1)) {
return -1;
}
else {
throw new NotDerivedClassTypeException();
}
}
if (t1 != null && Sets.newHashSet(t1.getAncestorTypes(context)).contains(t2)) {
return 1;
}
else if (t2 != null && Sets.newHashSet(t2.getAncestorTypes(context)).contains(t1)) {
return -1;
}
else {
return 0;
}
}
});
});
}
catch (NotDerivedClassTypeException ignored) {
return null;
}
}
private static final class NotDerivedClassTypeException extends RuntimeException {
}
private List<PyClassLikeType> getAllExplicitMetaClassTypes(@NotNull TypeEvalContext context) {
@@ -0,0 +1,24 @@
class M1(type):
def foo(cls):
pass
class M2(type):
def bar(cls):
pass
class C1(metaclass=M1):
pass
class C2(metaclass=M2):
pass
class D(C1, C2):
pass
print(D.<warning descr="Unresolved attribute reference 'foo' for class 'D'">foo</warning>()())
print(D.<warning descr="Unresolved attribute reference 'bar' for class 'D'">bar</warning>())
@@ -132,4 +132,9 @@ public class Py3UnresolvedReferencesInspectionTest extends PyTestCase {
public void testMostDerivedMetaClass() {
doTest();
}
// PY-17841
public void testNoMostDerivedMetaClass() {
doTest();
}
}