From 09c1f7085601a55703bec659a22ba2d1ffe71359 Mon Sep 17 00:00:00 2001 From: Semyon Proshev Date: Wed, 30 Dec 2020 17:20:22 +0300 Subject: [PATCH] Don't consider imported element as private if it is presented in dunder all (PY-46169) GitOrigin-RevId: b9f22ea3c7619f9db5b06e321ed3fe46cbaaea60 --- .../src/com/jetbrains/python/pyi/PyiFile.kt | 10 +++++++--- .../inspections/hiddenPyiImports/HiddenPyiImports.py | 3 ++- .../testData/pyi/inspections/hiddenPyiImports/m1.pyi | 5 ++++- 3 files changed, 13 insertions(+), 5 deletions(-) diff --git a/python/python-psi-impl/src/com/jetbrains/python/pyi/PyiFile.kt b/python/python-psi-impl/src/com/jetbrains/python/pyi/PyiFile.kt index ec03d90f2d93..58cb5c5b60f3 100644 --- a/python/python-psi-impl/src/com/jetbrains/python/pyi/PyiFile.kt +++ b/python/python-psi-impl/src/com/jetbrains/python/pyi/PyiFile.kt @@ -46,8 +46,9 @@ class PyiFile(viewProvider: FileViewProvider) : PyFileImpl(viewProvider, PyiLang if (exported && isPrivateName(name) && !resolvingBuiltinPathLike(name)) return emptyList() val baseResults = super.multiResolveName(name, exported) + val dunderAll = dunderAll ?: emptyList() return if (exported) - baseResults.filterNot { isPrivateImport((it as? ImportedResolveResult)?.definer) } + baseResults.filterNot { isPrivateImport((it as? ImportedResolveResult)?.definer, dunderAll) } else baseResults } @@ -56,9 +57,10 @@ class PyiFile(viewProvider: FileViewProvider) : PyFileImpl(viewProvider, PyiLang resolveState: ResolveState, lastParent: PsiElement?, place: PsiElement): Boolean { + val dunderAll = dunderAll ?: emptyList() val wrapper = object : DelegatingScopeProcessor(processor) { override fun execute(element: PsiElement, state: ResolveState): Boolean = when { - isPrivateImport(element) -> true + isPrivateImport(element, dunderAll) -> true element is PsiNamedElement && isPrivateName(element.name) -> true else -> super.execute(element, state) } @@ -68,7 +70,9 @@ class PyiFile(viewProvider: FileViewProvider) : PyFileImpl(viewProvider, PyiLang private fun isPrivateName(name: String?) = PyUtil.getInitialUnderscores(name) == 1 - private fun isPrivateImport(element: PsiElement?) = element is PyImportElement && element.asName == null + private fun isPrivateImport(element: PsiElement?, dunderAll: List): Boolean { + return element is PyImportElement && element.asName == null && element.visibleName !in dunderAll + } private fun resolvingBuiltinPathLike(name: String): Boolean { return name == PyNames.BUILTIN_PATH_LIKE && PyBuiltinCache.getInstance(this).builtinsFile == this diff --git a/python/testData/pyi/inspections/hiddenPyiImports/HiddenPyiImports.py b/python/testData/pyi/inspections/hiddenPyiImports/HiddenPyiImports.py index afc95ff16b69..241070da23f1 100644 --- a/python/testData/pyi/inspections/hiddenPyiImports/HiddenPyiImports.py +++ b/python/testData/pyi/inspections/hiddenPyiImports/HiddenPyiImports.py @@ -1,7 +1,8 @@ from m1 import foo from m1 import bar from m1 import bar_imported +from m1 import baz from m1 import m2 from m1 import m2_imported -print(foo, bar, bar_imported, m2, m2_imported) +print(foo, bar, bar_imported, baz, m2, m2_imported) diff --git a/python/testData/pyi/inspections/hiddenPyiImports/m1.pyi b/python/testData/pyi/inspections/hiddenPyiImports/m1.pyi index e48bfba11672..89128a47c8f0 100644 --- a/python/testData/pyi/inspections/hiddenPyiImports/m1.pyi +++ b/python/testData/pyi/inspections/hiddenPyiImports/m1.pyi @@ -1,4 +1,7 @@ from m2 import foo from m2 import bar as bar_imported +from m2 import baz import m2 -import m2 as m2_imported \ No newline at end of file +import m2 as m2_imported + +__all__ = ["baz"] \ No newline at end of file