mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
fixed PY-9262 Instance attribute defined outside init: false positive with superclass constructor call in class
This commit is contained in:
@@ -6,10 +6,11 @@ import com.intellij.psi.PsiElementVisitor;
|
||||
import com.jetbrains.python.PyBundle;
|
||||
import com.jetbrains.python.PyNames;
|
||||
import com.jetbrains.python.inspections.quickfix.PyMoveAttributeToInitQuickFix;
|
||||
import com.jetbrains.python.psi.PyClass;
|
||||
import com.jetbrains.python.psi.PyFunction;
|
||||
import com.jetbrains.python.psi.PyTargetExpression;
|
||||
import com.jetbrains.python.psi.*;
|
||||
import com.jetbrains.python.psi.impl.PyCallExpressionHelper;
|
||||
import com.jetbrains.python.psi.impl.PyClassImpl;
|
||||
import com.jetbrains.python.psi.types.PyClassType;
|
||||
import com.jetbrains.python.psi.types.PyType;
|
||||
import org.jetbrains.annotations.Nls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -52,9 +53,12 @@ public class PyAttributeOutsideInitInspection extends PyInspection {
|
||||
|
||||
Map<String, PyTargetExpression> attributesInInit = new HashMap<String, PyTargetExpression>();
|
||||
final PyFunction initMethod = containingClass.findMethodByName(PyNames.INIT, false);
|
||||
if (initMethod != null)
|
||||
if (initMethod != null) {
|
||||
PyClassImpl.collectInstanceAttributes(initMethod, attributesInInit);
|
||||
|
||||
collectAttributesFromSuper(attributesInInit, initMethod);
|
||||
}
|
||||
|
||||
Map<String, PyTargetExpression> attributes = new HashMap<String, PyTargetExpression>();
|
||||
PyClassImpl.collectInstanceAttributes(node, attributes);
|
||||
|
||||
@@ -66,5 +70,25 @@ public class PyAttributeOutsideInitInspection extends PyInspection {
|
||||
}
|
||||
}
|
||||
|
||||
private void collectAttributesFromSuper(Map<String, PyTargetExpression> attributesInInit, PyFunction initMethod) {
|
||||
final PyStatementList statementList = initMethod.getStatementList();
|
||||
if (statementList != null) {
|
||||
for (PyStatement statement : statementList.getStatements()) {
|
||||
if (statement instanceof PyExpressionStatement) {
|
||||
final PyExpression expression = ((PyExpressionStatement)statement).getExpression();
|
||||
if (expression instanceof PyCallExpression) {
|
||||
final PyType callType = PyCallExpressionHelper.getCallType((PyCallExpression)expression, myTypeEvalContext);
|
||||
if (callType instanceof PyClassType) {
|
||||
final PyClass superClass = ((PyClassType)callType).getPyClass();
|
||||
final PyFunction superInit = superClass.findMethodByName(PyNames.INIT, false);
|
||||
if (superInit != null) {
|
||||
PyClassImpl.collectInstanceAttributes(superInit, attributesInInit);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
__author__ = 'ktisha'
|
||||
|
||||
class Base(object):
|
||||
def __init__(self):
|
||||
self.my = 1
|
||||
|
||||
class Child(Base):
|
||||
def __init__(self):
|
||||
super(Child, self).__init__()
|
||||
|
||||
def f(self):
|
||||
self.my = 1
|
||||
+4
@@ -15,6 +15,10 @@ public class PyAttributeOutsideInitInspectionTest extends PyTestCase {
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testDefinedInSuperClass() {
|
||||
doTest();
|
||||
}
|
||||
|
||||
private void doTest() {
|
||||
myFixture.configureByFile("inspections/PyAttributeOutsideInitInspection/" + getTestName(true) + ".py");
|
||||
myFixture.enableInspections(PyAttributeOutsideInitInspection.class);
|
||||
|
||||
Reference in New Issue
Block a user