diff --git a/python/src/com/jetbrains/python/psi/impl/PyFileImpl.java b/python/src/com/jetbrains/python/psi/impl/PyFileImpl.java index 1fa8b886c6d6..dbb7ec3902e0 100644 --- a/python/src/com/jetbrains/python/psi/impl/PyFileImpl.java +++ b/python/src/com/jetbrains/python/psi/impl/PyFileImpl.java @@ -23,7 +23,6 @@ import com.intellij.lang.Language; import com.intellij.navigation.ItemPresentation; import com.intellij.openapi.fileTypes.FileType; import com.intellij.openapi.roots.ProjectFileIndex; -import com.intellij.openapi.util.Computable; import com.intellij.openapi.util.Key; import com.intellij.openapi.util.RecursionManager; import com.intellij.openapi.util.io.FileUtil; @@ -575,7 +574,24 @@ public class PyFileImpl extends PsiFileBase implements PyFile, PyExpression { if (callee instanceof PyQualifiedExpression) { final PyExpression qualifier = ((PyQualifiedExpression)callee).getQualifier(); if (qualifier != null && PyNames.ALL.equals(qualifier.getText())) { - // TODO handle append and extend with constant arguments here + final String calleeName = callee.getName(); + if ("append".equals(calleeName)) { + final PyStringLiteralExpression argument = node.getArgument(0, PyStringLiteralExpression.class); + if (argument != null) { + myResult.add(argument.getStringValue()); + return; + } + } + else if ("extend".equals(calleeName)) { + final PyExpression argument = node.getArgument(0, PyExpression.class); + if (argument != null) { + final List results = PyUtil.strListValue(argument); + if (results != null) { + myResult.addAll(results); + return; + } + } + } myDynamic = true; } } diff --git a/python/testData/resolve/multiFile/dontResolveToMissingNameInDynamicDunderAll/DontResolveToMissingNameInDynamicDunderAll.py b/python/testData/resolve/multiFile/dontResolveToMissingNameInDynamicDunderAll/DontResolveToMissingNameInDynamicDunderAll.py new file mode 100644 index 000000000000..e6ed3a8fc889 --- /dev/null +++ b/python/testData/resolve/multiFile/dontResolveToMissingNameInDynamicDunderAll/DontResolveToMissingNameInDynamicDunderAll.py @@ -0,0 +1,5 @@ +from m1 import * + + +print(internal_name) +# diff --git a/python/testData/resolve/multiFile/dontResolveToMissingNameInDynamicDunderAll/m1.py b/python/testData/resolve/multiFile/dontResolveToMissingNameInDynamicDunderAll/m1.py new file mode 100644 index 000000000000..7d79d318040b --- /dev/null +++ b/python/testData/resolve/multiFile/dontResolveToMissingNameInDynamicDunderAll/m1.py @@ -0,0 +1,13 @@ +__all__ = [ + 'foo', + 'bar' +] + +foo = 0 +bar = 1 + +__all__.append('quux') + +quux = 3 +internal_name = 4 + diff --git a/python/testSrc/com/jetbrains/python/PyMultiFileResolveTest.java b/python/testSrc/com/jetbrains/python/PyMultiFileResolveTest.java index 6d61dfaed139..13a1f32bf97f 100644 --- a/python/testSrc/com/jetbrains/python/PyMultiFileResolveTest.java +++ b/python/testSrc/com/jetbrains/python/PyMultiFileResolveTest.java @@ -473,6 +473,11 @@ public class PyMultiFileResolveTest extends PyMultiFileResolveTestCase { assertSameElements(doMultiResolveAndGetFileUrls("pkg/__init__.py"), "pkg/mod.py"); } + // PY-21088 + public void testDontResolveToMissingNameInDynamicDunderAll() { + assertNull(doResolve()); + } + @NotNull private List doMultiResolveAndGetFileUrls(@NotNull String currentFilePath) { myFixture.configureByFile(currentFilePath);