From 8faf6e47bbd933b1752fee6e4b23cefc02672643 Mon Sep 17 00:00:00 2001 From: Mikhail Golubev Date: Tue, 16 Mar 2021 18:10:58 +0300 Subject: [PATCH] PY-47304 Keep showing direct (non-fuzzy) module attributes after dot in completion Previously, we accidentally offered immediate attributes of a module only right after a dot in a non-imported qualified name (i.e., with an empty attribute name). If a qualified name of a fuzzy variant matched that of a direct attribute, it went unnoticed. However, if a name was non-trivially exported, as in case of "_pytest.mark.structures.MARK_GEN" exported as "pytest.mark", its expected name, as an attribute of pytest module, disappeared immediately as one started typing anything past the dot in "pytest.". GitOrigin-RevId: 5fbd7bd77fd1629f4d852b757d350cc182b991d7 --- ...vedModuleAttributeCompletionContributor.kt | 2 +- .../_impl.py | 2 ++ .../foo.py | 1 + .../main.after.py | 3 ++ .../main.py | 1 + ...otImportedQualifiedNameCompletionTest.java | 32 +++++++------------ 6 files changed, 20 insertions(+), 21 deletions(-) create mode 100644 python/testData/completion/notImportedQualifiedName/DirectModuleAttributesSuggestedForNonEmptyAttributePrefix/_impl.py create mode 100644 python/testData/completion/notImportedQualifiedName/DirectModuleAttributesSuggestedForNonEmptyAttributePrefix/foo.py create mode 100644 python/testData/completion/notImportedQualifiedName/DirectModuleAttributesSuggestedForNonEmptyAttributePrefix/main.after.py create mode 100644 python/testData/completion/notImportedQualifiedName/DirectModuleAttributesSuggestedForNonEmptyAttributePrefix/main.py diff --git a/python/python-psi-impl/src/com/jetbrains/python/codeInsight/completion/PyUnresolvedModuleAttributeCompletionContributor.kt b/python/python-psi-impl/src/com/jetbrains/python/codeInsight/completion/PyUnresolvedModuleAttributeCompletionContributor.kt index 3716644e960a..14fdf93cd2b0 100644 --- a/python/python-psi-impl/src/com/jetbrains/python/codeInsight/completion/PyUnresolvedModuleAttributeCompletionContributor.kt +++ b/python/python-psi-impl/src/com/jetbrains/python/codeInsight/completion/PyUnresolvedModuleAttributeCompletionContributor.kt @@ -119,7 +119,7 @@ class PyUnresolvedModuleAttributeCompletionContributor : CompletionContributor() .filter { it.containingFile != null } .filterNot { it is PsiFileSystemItem } .filterNot { it.name == null || it.name!!.startsWith('_') } - .filter { attribute.isEmpty() || resultMatchingCompleteReference.prefixMatcher.prefixMatches(it.name!!) } + .filter { attribute.isEmpty() || resultMatchingCompleteReference.prefixMatcher.prefixMatches("$packageName.${it.name}") } .mapNotNull { val qualifiedNameToSuggest = "$qualifier.${it.name}" if (suggestedQualifiedNames.add(qualifiedNameToSuggest)) { diff --git a/python/testData/completion/notImportedQualifiedName/DirectModuleAttributesSuggestedForNonEmptyAttributePrefix/_impl.py b/python/testData/completion/notImportedQualifiedName/DirectModuleAttributesSuggestedForNonEmptyAttributePrefix/_impl.py new file mode 100644 index 000000000000..4371a5a1f6ed --- /dev/null +++ b/python/testData/completion/notImportedQualifiedName/DirectModuleAttributesSuggestedForNonEmptyAttributePrefix/_impl.py @@ -0,0 +1,2 @@ +def bar(): + pass diff --git a/python/testData/completion/notImportedQualifiedName/DirectModuleAttributesSuggestedForNonEmptyAttributePrefix/foo.py b/python/testData/completion/notImportedQualifiedName/DirectModuleAttributesSuggestedForNonEmptyAttributePrefix/foo.py new file mode 100644 index 000000000000..201429ea524f --- /dev/null +++ b/python/testData/completion/notImportedQualifiedName/DirectModuleAttributesSuggestedForNonEmptyAttributePrefix/foo.py @@ -0,0 +1 @@ +from _impl import bar diff --git a/python/testData/completion/notImportedQualifiedName/DirectModuleAttributesSuggestedForNonEmptyAttributePrefix/main.after.py b/python/testData/completion/notImportedQualifiedName/DirectModuleAttributesSuggestedForNonEmptyAttributePrefix/main.after.py new file mode 100644 index 000000000000..1539f7deaf4f --- /dev/null +++ b/python/testData/completion/notImportedQualifiedName/DirectModuleAttributesSuggestedForNonEmptyAttributePrefix/main.after.py @@ -0,0 +1,3 @@ +import foo + +foo.bar() \ No newline at end of file diff --git a/python/testData/completion/notImportedQualifiedName/DirectModuleAttributesSuggestedForNonEmptyAttributePrefix/main.py b/python/testData/completion/notImportedQualifiedName/DirectModuleAttributesSuggestedForNonEmptyAttributePrefix/main.py new file mode 100644 index 000000000000..f94f20513ed2 --- /dev/null +++ b/python/testData/completion/notImportedQualifiedName/DirectModuleAttributesSuggestedForNonEmptyAttributePrefix/main.py @@ -0,0 +1 @@ +foo.ba \ No newline at end of file diff --git a/python/testSrc/com/jetbrains/python/PyNotImportedQualifiedNameCompletionTest.java b/python/testSrc/com/jetbrains/python/PyNotImportedQualifiedNameCompletionTest.java index eba87c58750b..2c77505b570c 100644 --- a/python/testSrc/com/jetbrains/python/PyNotImportedQualifiedNameCompletionTest.java +++ b/python/testSrc/com/jetbrains/python/PyNotImportedQualifiedNameCompletionTest.java @@ -75,38 +75,30 @@ public class PyNotImportedQualifiedNameCompletionTest extends PyTestCase { } public void testImportForModuleFunction() { - final String testName = getTestName(false); - myFixture.copyDirectoryToProject(testName, ""); - myFixture.configureByFile("main.py"); - myFixture.completeBasic(); - myFixture.checkResultByFile(testName + "/main.after.py"); + doTestBasicCompletion(); } public void testImportForModuleClass() { - final String testName = getTestName(false); - myFixture.copyDirectoryToProject(testName, ""); - myFixture.configureByFile("main.py"); - myFixture.completeBasic(); - myFixture.checkResultByFile(testName + "/main.after.py"); + doTestBasicCompletion(); } public void testImportForAlias() { - final String testName = getTestName(false); - myFixture.copyDirectoryToProject(testName, ""); - myFixture.configureByFile("main.py"); - myFixture.completeBasic(); - myFixture.checkResultByFile(testName + "/main.after.py"); + doTestBasicCompletion(); } public void testImportForAliasWithNonEmptyAttribute() { - final String testName = getTestName(false); - myFixture.copyDirectoryToProject(testName, ""); - myFixture.configureByFile("main.py"); - myFixture.completeBasic(); - myFixture.checkResultByFile(testName + "/main.after.py"); + doTestBasicCompletion(); } public void testUseImportPriorityWhenAddingImport() { + doTestBasicCompletion(); + } + + public void testDirectModuleAttributesSuggestedForNonEmptyAttributePrefix() { + doTestBasicCompletion(); + } + + private void doTestBasicCompletion() { final String testName = getTestName(false); myFixture.copyDirectoryToProject(testName, ""); myFixture.configureByFile("main.py");