From 45beb4e27385715ef487921a2a333978c1684e3f Mon Sep 17 00:00:00 2001 From: Semyon Proshev Date: Tue, 31 Oct 2017 21:23:58 +0300 Subject: [PATCH] If smth is listed in `__all__` but not found, add module to results. (PY-26243, PY-25751) --- .../codeInsight/PyDunderAllReference.java | 36 +++++-------------- .../jetbrains/python/psi/impl/PyFileImpl.java | 21 ++++------- .../pkg/__init__.py | 1 + .../NotImportedModuleInDunderAll/pkg/aaa.py | 0 .../pkg/__init__.py | 1 + .../pkg/aaa/__init__.py | 0 .../pkg/__init__.py | 1 + .../NotImportedModuleInDunderAll/pkg/aaa.py | 0 .../pkg/__init__.py | 1 + .../pkg/aaa/__init__.py | 0 .../com/jetbrains/python/PyTypeTest.java | 14 ++++++++ .../PyUnresolvedReferencesInspectionTest.java | 13 +++++-- 12 files changed, 44 insertions(+), 44 deletions(-) create mode 100644 python/testData/inspections/PyUnresolvedReferencesInspection/NotImportedModuleInDunderAll/pkg/__init__.py create mode 100644 python/testData/inspections/PyUnresolvedReferencesInspection/NotImportedModuleInDunderAll/pkg/aaa.py create mode 100644 python/testData/inspections/PyUnresolvedReferencesInspection/NotImportedPackageInDunderAll/pkg/__init__.py create mode 100644 python/testData/inspections/PyUnresolvedReferencesInspection/NotImportedPackageInDunderAll/pkg/aaa/__init__.py create mode 100644 python/testData/types/NotImportedModuleInDunderAll/pkg/__init__.py create mode 100644 python/testData/types/NotImportedModuleInDunderAll/pkg/aaa.py create mode 100644 python/testData/types/NotImportedPackageInDunderAll/pkg/__init__.py create mode 100644 python/testData/types/NotImportedPackageInDunderAll/pkg/aaa/__init__.py diff --git a/python/src/com/jetbrains/python/codeInsight/PyDunderAllReference.java b/python/src/com/jetbrains/python/codeInsight/PyDunderAllReference.java index 5e09eb45e1ce..c13882ca0aa7 100644 --- a/python/src/com/jetbrains/python/codeInsight/PyDunderAllReference.java +++ b/python/src/com/jetbrains/python/codeInsight/PyDunderAllReference.java @@ -1,35 +1,18 @@ -/* - * Copyright 2000-2017 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ +// Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. package com.jetbrains.python.codeInsight; import com.intellij.codeInsight.lookup.LookupElement; import com.intellij.codeInsight.lookup.LookupElementBuilder; import com.intellij.openapi.util.TextRange; -import com.intellij.psi.PsiElement; -import com.intellij.psi.PsiNamedElement; -import com.intellij.psi.PsiReferenceBase; -import com.intellij.psi.ResolveState; +import com.intellij.psi.*; import com.intellij.psi.scope.BaseScopeProcessor; import com.intellij.util.ArrayUtil; import com.intellij.util.containers.ContainerUtil; import com.jetbrains.python.PyNames; import com.jetbrains.python.psi.*; import com.jetbrains.python.psi.impl.LightNamedElement; -import com.jetbrains.python.psi.types.PyModuleType; import com.jetbrains.python.psi.resolve.RatedResolveResult; +import com.jetbrains.python.psi.types.PyModuleType; import one.util.streamex.StreamEx; import org.jetbrains.annotations.NotNull; @@ -41,7 +24,7 @@ import java.util.Set; /** * @author yole */ -public class PyDunderAllReference extends PsiReferenceBase { +public class PyDunderAllReference extends PsiPolyVariantReferenceBase { public PyDunderAllReference(@NotNull PyStringLiteralExpression element) { super(element); final List ranges = element.getStringValueTextRanges(); @@ -51,12 +34,13 @@ public class PyDunderAllReference extends PsiReferenceBase resolveResults = PyUtil.filterTopPriorityResults(file.multiResolveName(name)); + final List resolveResults = file.multiResolveName(name); final boolean onlyDunderAlls = StreamEx .of(resolveResults) @@ -64,11 +48,9 @@ public class PyDunderAllReference extends PsiReferenceBase resolvedElement instanceof PyTargetExpression && PyNames.ALL.equals(((PyTargetExpression)resolvedElement).getName())); - if (onlyDunderAlls) return null; + if (onlyDunderAlls) return ResolveResult.EMPTY_ARRAY; - final RatedResolveResult resolveResult = ContainerUtil.getFirstItem(resolveResults); - if (resolveResult == null) return null; - return resolveResult.getElement(); + return ContainerUtil.toArray(resolveResults, RatedResolveResult.EMPTY_ARRAY); } @NotNull diff --git a/python/src/com/jetbrains/python/psi/impl/PyFileImpl.java b/python/src/com/jetbrains/python/psi/impl/PyFileImpl.java index fa6bf9202f40..7e66bb95cf24 100644 --- a/python/src/com/jetbrains/python/psi/impl/PyFileImpl.java +++ b/python/src/com/jetbrains/python/psi/impl/PyFileImpl.java @@ -1,18 +1,4 @@ -/* - * Copyright 2000-2017 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ +// Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. package com.jetbrains.python.psi.impl; import com.google.common.collect.Lists; @@ -426,6 +412,11 @@ public class PyFileImpl extends PsiFileBase implements PyFile, PyExpression { final PsiElement allElement = findExportedName(PyNames.ALL); final ResolveResultList allFallbackResults = new ResolveResultList(); allFallbackResults.poke(allElement, RatedResolveResult.RATE_LOW); + + PyResolveImportUtil + .resolveModuleAt(QualifiedName.fromComponents(name), getContainingDirectory(), PyResolveImportUtil.fromFoothold(this)) + .forEach(module -> allFallbackResults.poke(module, RatedResolveResult.RATE_LOW)); + return allFallbackResults; } return Collections.emptyList(); diff --git a/python/testData/inspections/PyUnresolvedReferencesInspection/NotImportedModuleInDunderAll/pkg/__init__.py b/python/testData/inspections/PyUnresolvedReferencesInspection/NotImportedModuleInDunderAll/pkg/__init__.py new file mode 100644 index 000000000000..32bd63706d3c --- /dev/null +++ b/python/testData/inspections/PyUnresolvedReferencesInspection/NotImportedModuleInDunderAll/pkg/__init__.py @@ -0,0 +1 @@ +__all__ = ["aaa"] \ No newline at end of file diff --git a/python/testData/inspections/PyUnresolvedReferencesInspection/NotImportedModuleInDunderAll/pkg/aaa.py b/python/testData/inspections/PyUnresolvedReferencesInspection/NotImportedModuleInDunderAll/pkg/aaa.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/python/testData/inspections/PyUnresolvedReferencesInspection/NotImportedPackageInDunderAll/pkg/__init__.py b/python/testData/inspections/PyUnresolvedReferencesInspection/NotImportedPackageInDunderAll/pkg/__init__.py new file mode 100644 index 000000000000..32bd63706d3c --- /dev/null +++ b/python/testData/inspections/PyUnresolvedReferencesInspection/NotImportedPackageInDunderAll/pkg/__init__.py @@ -0,0 +1 @@ +__all__ = ["aaa"] \ No newline at end of file diff --git a/python/testData/inspections/PyUnresolvedReferencesInspection/NotImportedPackageInDunderAll/pkg/aaa/__init__.py b/python/testData/inspections/PyUnresolvedReferencesInspection/NotImportedPackageInDunderAll/pkg/aaa/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/python/testData/types/NotImportedModuleInDunderAll/pkg/__init__.py b/python/testData/types/NotImportedModuleInDunderAll/pkg/__init__.py new file mode 100644 index 000000000000..32bd63706d3c --- /dev/null +++ b/python/testData/types/NotImportedModuleInDunderAll/pkg/__init__.py @@ -0,0 +1 @@ +__all__ = ["aaa"] \ No newline at end of file diff --git a/python/testData/types/NotImportedModuleInDunderAll/pkg/aaa.py b/python/testData/types/NotImportedModuleInDunderAll/pkg/aaa.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/python/testData/types/NotImportedPackageInDunderAll/pkg/__init__.py b/python/testData/types/NotImportedPackageInDunderAll/pkg/__init__.py new file mode 100644 index 000000000000..32bd63706d3c --- /dev/null +++ b/python/testData/types/NotImportedPackageInDunderAll/pkg/__init__.py @@ -0,0 +1 @@ +__all__ = ["aaa"] \ No newline at end of file diff --git a/python/testData/types/NotImportedPackageInDunderAll/pkg/aaa/__init__.py b/python/testData/types/NotImportedPackageInDunderAll/pkg/aaa/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/python/testSrc/com/jetbrains/python/PyTypeTest.java b/python/testSrc/com/jetbrains/python/PyTypeTest.java index a2245b18ce05..77c5235f652d 100644 --- a/python/testSrc/com/jetbrains/python/PyTypeTest.java +++ b/python/testSrc/com/jetbrains/python/PyTypeTest.java @@ -2302,6 +2302,20 @@ public class PyTypeTest extends PyTestCase { ); } + // PY-25751 + public void testNotImportedModuleInDunderAll() { + doMultiFileTest("Union[aaa.py, Any]", + "from pkg import *\n" + + "expr = aaa"); + } + + // PY-25751 + public void testNotImportedPackageInDunderAll() { + doMultiFileTest("Union[__init__.py, Any]", + "from pkg import *\n" + + "expr = aaa"); + } + // PY-26269 public void testDontReplaceDictValueWithReceiverType() { runWithLanguageLevel( diff --git a/python/testSrc/com/jetbrains/python/inspections/PyUnresolvedReferencesInspectionTest.java b/python/testSrc/com/jetbrains/python/inspections/PyUnresolvedReferencesInspectionTest.java index 98118537bbbd..9aead724d11d 100644 --- a/python/testSrc/com/jetbrains/python/inspections/PyUnresolvedReferencesInspectionTest.java +++ b/python/testSrc/com/jetbrains/python/inspections/PyUnresolvedReferencesInspectionTest.java @@ -12,7 +12,6 @@ import com.jetbrains.python.debugger.PyDebuggerEditorsProvider; import com.jetbrains.python.fixtures.PyInspectionTestCase; import com.jetbrains.python.inspections.unresolvedReference.PyUnresolvedReferencesInspection; import com.jetbrains.python.psi.LanguageLevel; -import com.jetbrains.python.psi.PyFile; import com.jetbrains.python.psi.impl.PyExpressionCodeFragmentImpl; import org.jdom.Element; import org.jetbrains.annotations.NotNull; @@ -571,7 +570,7 @@ public class PyUnresolvedReferencesInspectionTest extends PyInspectionTestCase { assertEquals("foo.py", fooVFile.getName()); final PsiFile fooPsiFile = PsiManager.getInstance(myFixture.getProject()).findFile(fooVFile); - assertNotParsed((PyFile)fooPsiFile); + assertNotParsed(fooPsiFile); } // PY-23164 @@ -648,6 +647,16 @@ public class PyUnresolvedReferencesInspectionTest extends PyInspectionTestCase { doTest(); } + // PY-26243 + public void testNotImportedModuleInDunderAll() { + doMultiFileTest("pkg/__init__.py"); + } + + // PY-26243 + public void testNotImportedPackageInDunderAll() { + doMultiFileTest("pkg/__init__.py"); + } + @NotNull @Override protected Class getInspectionClass() {