correct semantics of __slots__ with inheritance (PY-5939)

This commit is contained in:
Dmitry Jemerov
2012-04-26 09:40:00 +02:00
parent d7fecf6cd7
commit 69688bf2ca
3 changed files with 35 additions and 2 deletions
@@ -154,10 +154,24 @@ public class PyUnresolvedReferencesInspection extends PyInspection {
final PyClass pyClass = ((PyClassType)type).getPyClass();
if (pyClass != null && pyClass.isNewStyleClass()) {
final List<String> slots = pyClass.getSlots();
if (slots != null && !slots.contains(node.getReferencedName()) && !slots.contains("__dict__")) {
final String attrName = node.getReferencedName();
if (slots != null && !slots.contains(attrName) && !slots.contains(PyNames.DICT)) {
for (PyClassRef ref : pyClass.iterateAncestors()) {
final PyClass ancestor = ref.getPyClass();
if (ancestor == null) {
return;
}
if (PyNames.OBJECT.equals(ancestor.getName())) {
break;
}
final List<String> ancestorSlots = ancestor.getSlots();
if (ancestorSlots == null || ancestorSlots.contains(attrName) || ancestorSlots.contains(PyNames.DICT)) {
return;
}
}
final ASTNode nameNode = node.getNameElement();
final PsiElement e = nameNode != null ? nameNode.getPsi() : node;
registerProblem(e, "'" + pyClass.getName() + "' object has no attribute '" + node.getReferencedName() + "'");
registerProblem(e, "'" + pyClass.getName() + "' object has no attribute '" + attrName + "'");
}
}
}
@@ -0,0 +1,15 @@
class A(object):
__slots__ = ['a', 'b']
def __init__(self):
self.a = None # <- all ok here
self.b = None # <- all ok here
class C(A):
__slots__ = ['c', 'd']
def __init__(self, c):
super(C, self).__init__()
self.c = c
self.d = self.b
if self.c:
self.a = 10
@@ -32,6 +32,10 @@ public class PyUnresolvedReferencesInspectionTest extends PyTestCase {
doTest();
}
public void testSlotsSubclass() { // PY-5939
doTest();
}
public void testImportExceptImportError() {
doTest();
}