From d2e52ec04a1f20cc1f3ce0c5a832297d72c208a4 Mon Sep 17 00:00:00 2001 From: Semyon Proshev Date: Thu, 22 Nov 2018 18:14:46 +0300 Subject: [PATCH] Implement two-level white list for stub packages advertisement (PY-32135) --- .../typing/PyStubPackagesAdvertiser.kt | 80 +++++++++---------- 1 file changed, 37 insertions(+), 43 deletions(-) diff --git a/python/src/com/jetbrains/python/codeInsight/typing/PyStubPackagesAdvertiser.kt b/python/src/com/jetbrains/python/codeInsight/typing/PyStubPackagesAdvertiser.kt index 3b150a347e6d..3b3c83ab82ae 100644 --- a/python/src/com/jetbrains/python/codeInsight/typing/PyStubPackagesAdvertiser.kt +++ b/python/src/com/jetbrains/python/codeInsight/typing/PyStubPackagesAdvertiser.kt @@ -36,7 +36,16 @@ import javax.swing.JComponent class PyStubPackagesAdvertiser : PyInspection() { companion object { - private val WHITE_LIST = mapOf("django" to "Django", "numpy" to "numpy") // top-level package to package on PyPI + // file-level suggestion will be shown for packages below + private val FORCED = mapOf("django" to "Django", "numpy" to "numpy") // top-level package to package on PyPI + + // notification will be shown for packages below + private val CHECKED = mapOf("pyspark" to "pyspark", + "ordered_set" to "ordered-set", + "docutils" to "docutils", + "coincurve" to "coincurve", + "PyQt5" to "PyQt5", + "gi" to "PyGObject") // top-level package to package on PyPI private val BALLOON_SHOWING = Key.create("showingStubPackagesAdvertiserBalloon") private val BALLOON_NOTIFICATIONS = NotificationGroup("Python Stub Packages Advertiser", NotificationDisplayType.STICKY_BALLOON, false) @@ -104,22 +113,22 @@ class PyStubPackagesAdvertiser : PyInspection() { val cache = ServiceManager.getService(PyStubPackagesAdvertiserCache::class.java).forSdk(sdk) - processWhiteListedPackages(file, sources, module, sdk, availablePackages, installedPackages, cache, problemsHolder) - processNotWhiteListedPackages(file, sources, module, sdk, availablePackages, installedPackages, cache) + processForcedPackages(file, sources, module, sdk, availablePackages, installedPackages, cache, problemsHolder) + processCheckedPackages(file, sources, module, sdk, availablePackages, installedPackages, cache) } - private fun processWhiteListedPackages(file: PyFile, - sources: Set, - module: Module, - sdk: Sdk, - availablePackages: List, - installedPackages: List, - cache: Cache>, - problemsHolder: ProblemsHolder) { - val (sourcesToLoad, cached) = splitIntoNotCachedAndCached(whiteListedSourcesToProcess(sources), cache) + private fun processForcedPackages(file: PyFile, + sources: Set, + module: Module, + sdk: Sdk, + availablePackages: List, + installedPackages: List, + cache: Cache>, + problemsHolder: ProblemsHolder) { + val (sourcesToLoad, cached) = splitIntoNotCachedAndCached(forcedSourcesToProcess(sources), cache) val sourceToStubPkgsAvailableToInstall = sourceToStubPackagesAvailableToInstall( - whiteListedSourceToInstalledRuntimeAndStubPackages(sourcesToLoad, installedPackages), + sourceToInstalledRuntimeAndStubPackages(sourcesToLoad, FORCED, installedPackages), availablePackages ) @@ -138,20 +147,20 @@ class PyStubPackagesAdvertiser : PyInspection() { } } - private fun processNotWhiteListedPackages(file: PyFile, - sources: Set, - module: Module, - sdk: Sdk, - availablePackages: List, - installedPackages: List, - cache: Cache>) { + private fun processCheckedPackages(file: PyFile, + sources: Set, + module: Module, + sdk: Sdk, + availablePackages: List, + installedPackages: List, + cache: Cache>) { val project = file.project if (project.getUserData(BALLOON_SHOWING) == true) return - val (sourcesToLoad, cached) = splitIntoNotCachedAndCached(notWhiteListedSourcesToProcess(sources), cache) + val (sourcesToLoad, cached) = splitIntoNotCachedAndCached(checkedSourcesToProcess(sources), cache) val sourceToStubPkgsAvailableToInstall = sourceToStubPackagesAvailableToInstall( - notWhiteListedSourceToInstalledRuntimeAndStubPackages(sourcesToLoad, installedPackages), + sourceToInstalledRuntimeAndStubPackages(sourcesToLoad, CHECKED, installedPackages), availablePackages ) @@ -205,9 +214,9 @@ class PyStubPackagesAdvertiser : PyInspection() { } } - private fun whiteListedSourcesToProcess(sources: Set) = sources.filterTo(mutableSetOf()) { it in WHITE_LIST } + private fun forcedSourcesToProcess(sources: Set) = sources.filterTo(mutableSetOf()) { it in FORCED } - private fun notWhiteListedSourcesToProcess(sources: Set) = sources.filterNotTo(mutableSetOf()) { it in WHITE_LIST } + private fun checkedSourcesToProcess(sources: Set) = sources.filterTo(mutableSetOf()) { it in CHECKED } private fun splitIntoNotCachedAndCached(sources: Set, cache: Cache>): Pair, Set> { @@ -240,12 +249,13 @@ class PyStubPackagesAdvertiser : PyInspection() { return notCached to cached } - private fun whiteListedSourceToInstalledRuntimeAndStubPackages(sourcesToLoad: Set, - installedPackages: List): Map>> { + private fun sourceToInstalledRuntimeAndStubPackages(sourcesToLoad: Set, + sourceToPackage: Map, + installedPackages: List): Map>> { val result = mutableMapOf>>() for (source in sourcesToLoad) { - val pkgName = WHITE_LIST[source] ?: continue + val pkgName = sourceToPackage[source] ?: continue if (ignoredPackages.contains(pkgName)) continue installedRuntimeAndStubPackages(pkgName, installedPackages)?.let { result.put(source, listOf(it)) } @@ -254,22 +264,6 @@ class PyStubPackagesAdvertiser : PyInspection() { return result } - private fun notWhiteListedSourceToInstalledRuntimeAndStubPackages(sourcesToLoad: Set, - installedPackages: List): Map>> { - val result = mutableMapOf>>() - - for (source in sourcesToLoad) { - val packageNames = PyPIPackageUtil.PACKAGES_TOPLEVEL[source] ?: listOf(source) - - result[source] = packageNames.mapNotNull { - if (ignoredPackages.contains(it)) null - else installedRuntimeAndStubPackages(it, installedPackages) - } - } - - return result - } - private fun sourceToStubPackagesAvailableToInstall(sourceToInstalledRuntimeAndStubPkgs: Map>>, availablePackages: List): Map> { if (sourceToInstalledRuntimeAndStubPkgs.isEmpty()) return emptyMap()