diff --git a/python/python-psi-impl/src/com/jetbrains/python/psi/impl/PyClassImpl.java b/python/python-psi-impl/src/com/jetbrains/python/psi/impl/PyClassImpl.java index daffa9749787..e9d492821c4f 100644 --- a/python/python-psi-impl/src/com/jetbrains/python/psi/impl/PyClassImpl.java +++ b/python/python-psi-impl/src/com/jetbrains/python/psi/impl/PyClassImpl.java @@ -1107,7 +1107,7 @@ public class PyClassImpl extends PyBaseElementImpl implements PyCla private List collectInstanceAttributes(Map scopesToSkip) { Map result = new HashMap<>(); - collectAttributesInConstructors(result); + collectAttributesInConstructors(result, scopesToSkip); Set existing = new HashSet<>(result.keySet()); final PyFunction[] methods = getMethods(); for (PyFunction method : methods) { @@ -1117,16 +1117,20 @@ public class PyClassImpl extends PyBaseElementImpl implements PyCla return new ArrayList<>(result.values()); } - private void collectAttributesInConstructors(Map result) { + private void collectAttributesInConstructors(Map result, + Map scopesToSkip) { PyFunction newMethod = findMethodByName(PyNames.NEW, false, null); if (newMethod != null) { for (PyTargetExpression target : getTargetExpressions(newMethod)) { - result.put(target.getName(), target); + String name = target.getName(); + if (scopesToSkip.get(name) != newMethod) { + result.put(name, target); + } } } - PyFunctionImpl initMethod = (PyFunctionImpl)findMethodByName(PyNames.INIT, false, null); + PyFunction initMethod = findMethodByName(PyNames.INIT, false, null); if (initMethod != null) { - collectInstanceAttributes(initMethod, result); + collectInstanceAttributes(initMethod, result, Collections.emptySet(), scopesToSkip); } } diff --git a/python/testData/resolve/InstanceAttrBelowInInitAndOtherMethodAbove.py b/python/testData/resolve/InstanceAttrBelowInInitAndOtherMethodAbove.py new file mode 100644 index 000000000000..2b47ea341ac9 --- /dev/null +++ b/python/testData/resolve/InstanceAttrBelowInInitAndOtherMethodAbove.py @@ -0,0 +1,9 @@ +class C: + def g(self): + self.foo = 0 + + def __init__(self): + self.g() + print(self.foo) # -> self.foo in g + # + self.foo = 1 diff --git a/python/testSrc/com/jetbrains/python/Py3ResolveTest.java b/python/testSrc/com/jetbrains/python/Py3ResolveTest.java index 16afd9c8d313..38d0a5edde09 100644 --- a/python/testSrc/com/jetbrains/python/Py3ResolveTest.java +++ b/python/testSrc/com/jetbrains/python/Py3ResolveTest.java @@ -836,4 +836,10 @@ public class Py3ResolveTest extends PyResolveTestCase { PyTargetExpression target = assertResolvesTo(PyTargetExpression.class, "foo"); assertEquals("self.foo = 1", target.getParent().getText()); } + + public void testInstanceAttrBelowInInitAndOtherMethodAbove() { + final PyTargetExpression target = assertResolvesTo(PyTargetExpression.class, "foo"); + final PyFunction function = assertInstanceOf(ScopeUtil.getScopeOwner(target), PyFunction.class); + assertEquals("g", function.getName()); + } }