diff --git a/python/python-psi-impl/src/com/jetbrains/python/codeInsight/completion/PyClassNameCompletionContributor.java b/python/python-psi-impl/src/com/jetbrains/python/codeInsight/completion/PyClassNameCompletionContributor.java index bfc58bdd547d..63ee2f36d55c 100644 --- a/python/python-psi-impl/src/com/jetbrains/python/codeInsight/completion/PyClassNameCompletionContributor.java +++ b/python/python-psi-impl/src/com/jetbrains/python/codeInsight/completion/PyClassNameCompletionContributor.java @@ -7,8 +7,6 @@ import com.intellij.codeInsight.completion.InsertHandler; import com.intellij.codeInsight.completion.PrioritizedLookupElement; import com.intellij.codeInsight.lookup.LookupElement; import com.intellij.codeInsight.lookup.LookupElementBuilder; -import com.intellij.navigation.ItemPresentation; -import com.intellij.navigation.NavigationItem; import com.intellij.openapi.progress.ProgressManager; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Condition; @@ -24,6 +22,7 @@ import com.intellij.util.containers.ContainerUtil; import com.jetbrains.python.codeInsight.controlflow.ScopeOwner; import com.jetbrains.python.codeInsight.dataflow.scope.ScopeUtil; import com.jetbrains.python.psi.*; +import com.jetbrains.python.psi.resolve.QualifiedNameFinder; import com.jetbrains.python.psi.search.PySearchUtilBase; import com.jetbrains.python.psi.stubs.PyClassNameIndex; import com.jetbrains.python.psi.stubs.PyFunctionNameIndex; @@ -125,16 +124,15 @@ public class PyClassNameCompletionContributor extends PyExtendedCompletionContri ProgressManager.checkCanceled(); if (!condition.value(element)) return true; String name = element.getName(); - ItemPresentation itemPresentation = ((NavigationItem)element).getPresentation(); - if (name == null || itemPresentation == null) return true; - String locationString = itemPresentation.getLocationString(); - if (locationString == null) return true; - String uniquenessKey = name + locationString; - if (alreadySuggested.add(uniquenessKey)) { + if (name == null) return true; + QualifiedName importPath = QualifiedNameFinder.findCanonicalImportPath(element, targetFile); + if (importPath == null) return true; + String qualifiedName = importPath + "." + name; + if (alreadySuggested.add(qualifiedName)) { LookupElementBuilder lookupElement = LookupElementBuilder .createWithSmartPointer(name, element) .withIcon(element.getIcon(0)) - .withTailText(" " + locationString, true) + .withTailText(" (" + importPath + ")", true) .withInsertHandler(insertHandler); resultSet.addElement(elementHandler.apply(lookupElement)); } diff --git a/python/testData/completion/className/canonicalImportPathUsedAsLookupTailText/canonicalImportPathUsedAsLookupTailText.py b/python/testData/completion/className/canonicalImportPathUsedAsLookupTailText/canonicalImportPathUsedAsLookupTailText.py new file mode 100644 index 000000000000..727760c19d9d --- /dev/null +++ b/python/testData/completion/className/canonicalImportPathUsedAsLookupTailText/canonicalImportPathUsedAsLookupTailText.py @@ -0,0 +1 @@ +my_ diff --git a/python/testData/completion/className/canonicalImportPathUsedAsLookupTailText/pkg/__init__.py b/python/testData/completion/className/canonicalImportPathUsedAsLookupTailText/pkg/__init__.py new file mode 100644 index 000000000000..c0e2262456a3 --- /dev/null +++ b/python/testData/completion/className/canonicalImportPathUsedAsLookupTailText/pkg/__init__.py @@ -0,0 +1 @@ +from .mod import my_func diff --git a/python/testData/completion/className/canonicalImportPathUsedAsLookupTailText/pkg/mod.py b/python/testData/completion/className/canonicalImportPathUsedAsLookupTailText/pkg/mod.py new file mode 100644 index 000000000000..85f09741347e --- /dev/null +++ b/python/testData/completion/className/canonicalImportPathUsedAsLookupTailText/pkg/mod.py @@ -0,0 +1,5 @@ +def my_func(): + pass + + +my_var = 42 diff --git a/python/testSrc/com/jetbrains/python/PyClassNameCompletionTest.java b/python/testSrc/com/jetbrains/python/PyClassNameCompletionTest.java index ba66b2d85cbc..2ee54383f31e 100644 --- a/python/testSrc/com/jetbrains/python/PyClassNameCompletionTest.java +++ b/python/testSrc/com/jetbrains/python/PyClassNameCompletionTest.java @@ -8,6 +8,8 @@ import com.intellij.psi.PsiDirectory; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFileSystemItem; import com.intellij.psi.codeStyle.CommonCodeStyleSettings; +import com.intellij.testFramework.fixtures.TestLookupElementPresentation; +import com.intellij.util.containers.ContainerUtil; import com.jetbrains.python.codeInsight.PyCodeInsightSettings; import com.jetbrains.python.fixtures.PyTestCase; import com.jetbrains.python.formatter.PyCodeStyleSettings; @@ -164,6 +166,20 @@ public class PyClassNameCompletionTest extends PyTestCase { assertEquals(1, Collections.frequency(allVariants, "my_func")); } + // PY-45541 + public void testCanonicalImportPathUsedAsLookupTailText() { + LookupElement[] lookupElements = doExtendedCompletion(); + LookupElement reexportedFunc = ContainerUtil.find(lookupElements, variant -> variant.getLookupString().equals("my_func")); + assertNotNull(reexportedFunc); + TestLookupElementPresentation funcPresentation = TestLookupElementPresentation.renderReal(reexportedFunc); + assertEquals(" (pkg)", funcPresentation.getTailText()); + + LookupElement notExportedVar = ContainerUtil.find(lookupElements, variant -> variant.getLookupString().equals("my_var")); + assertNotNull(notExportedVar); + TestLookupElementPresentation varPresentation = TestLookupElementPresentation.renderReal(notExportedVar); + assertEquals(" (pkg.mod)", varPresentation.getTailText()); + } + private void doTest() { LookupElement[] lookupElements = doExtendedCompletion(); if (lookupElements != null) {