PY-85634 Adapt PyInterpreterInspection to Kotlin style

Follow-up to IJ-MR-178613

GitOrigin-RevId: 25175f413a9062b43e1b2e2df2ea1082ebd639de
This commit is contained in:
Alexey Katsman
2025-11-25 18:47:50 +00:00
committed by intellij-monorepo-bot
parent 93a8360b34
commit c6f0af15f0
3 changed files with 186 additions and 315 deletions
@@ -6,7 +6,6 @@ import com.intellij.codeInspection.ProblemDescriptor
import com.intellij.ide.actions.ShowSettingsUtilImpl
import com.intellij.openapi.module.Module
import com.intellij.openapi.module.ModuleManager
import com.intellij.openapi.options.ConfigurableGroup
import com.intellij.openapi.options.ex.ConfigurableExtensionPointUtil
import com.intellij.openapi.options.ex.ConfigurableVisitor
import com.intellij.openapi.project.Project
@@ -17,16 +16,12 @@ import com.intellij.util.PlatformUtils
import com.jetbrains.python.PyPsiBundle
class InterpreterSettingsQuickFix(private val myModule: Module?) : LocalQuickFix {
override fun getFamilyName(): String {
return if (PlatformUtils.isPyCharm())
PyPsiBundle.message("INSP.interpreter.interpreter.settings")
else
PyPsiBundle.message("INSP.interpreter.configure.python.interpreter")
}
override fun getFamilyName(): String = if (PlatformUtils.isPyCharm())
PyPsiBundle.message("INSP.interpreter.interpreter.settings")
else
PyPsiBundle.message("INSP.interpreter.configure.python.interpreter")
override fun startInWriteAction(): Boolean {
return false
}
override fun startInWriteAction(): Boolean = false
override fun applyFix(project: Project, descriptor: ProblemDescriptor) {
showPythonInterpreterSettings(project, myModule)
@@ -36,8 +31,8 @@ class InterpreterSettingsQuickFix(private val myModule: Module?) : LocalQuickFix
fun showPythonInterpreterSettings(project: Project, module: Module?) {
val id = "com.jetbrains.python.configuration.PyActiveSdkModuleConfigurable"
val group = ConfigurableExtensionPointUtil.getConfigurableGroup(project, true)
if (ConfigurableVisitor.findById(id, mutableListOf<ConfigurableGroup?>(group)) != null) {
ShowSettingsUtilImpl.Companion.showSettingsDialog(project, id, null)
if (ConfigurableVisitor.findById(id, listOf(group)) != null) {
ShowSettingsUtilImpl.showSettingsDialog(project, id, null)
return
}
@@ -51,8 +46,9 @@ class InterpreterSettingsQuickFix(private val myModule: Module?) : LocalQuickFix
}
private fun justOneModuleInheritingSdk(project: Project, module: Module): Boolean {
return ProjectRootManager.getInstance(project).getProjectSdk() == null &&
ModuleRootManager.getInstance(module).isSdkInherited() && ModuleManager.Companion.getInstance(project).modules.size < 2
return ProjectRootManager.getInstance(project).projectSdk == null &&
ModuleRootManager.getInstance(module).isSdkInherited &&
ModuleManager.getInstance(project).modules.size < 2
}
}
}
@@ -9,19 +9,20 @@ import com.intellij.codeInspection.ProblemsHolder
import com.intellij.codeInspection.util.InspectionMessage
import com.intellij.codeInspection.util.IntentionFamilyName
import com.intellij.codeInspection.util.IntentionName
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.components.Service
import com.intellij.openapi.components.service
import com.intellij.openapi.module.Module
import com.intellij.openapi.module.ModuleUtilCore
import com.intellij.openapi.progress.runBlockingMaybeCancellable
import com.intellij.openapi.project.Project
import com.intellij.openapi.projectRoots.Sdk
import com.intellij.openapi.roots.ProjectRootManager
import com.intellij.openapi.roots.ui.configuration.projectRoot.ProjectSdksModel
import com.intellij.openapi.util.Condition
import com.intellij.openapi.util.UserDataHolderBase
import com.intellij.psi.PsiElementVisitor
import com.intellij.python.sdkConfigurator.common.detectSdkForModulesIn
import com.intellij.python.sdkConfigurator.common.enableSDKAutoConfigurator
import com.intellij.util.PathUtil
import com.intellij.util.containers.ContainerUtil
import com.intellij.util.containers.toArray
import com.jetbrains.python.PyPsiBundle
import com.jetbrains.python.PythonIdeLanguageCustomization
import com.jetbrains.python.inspections.PyInspection
@@ -31,302 +32,218 @@ import com.jetbrains.python.psi.LanguageLevel
import com.jetbrains.python.psi.PyFile
import com.jetbrains.python.psi.impl.PyBuiltinCache
import com.jetbrains.python.psi.types.TypeEvalContext
import com.jetbrains.python.sdk.PyDetectedSdk
import com.jetbrains.python.sdk.PySdkPopupFactory
import com.jetbrains.python.sdk.PythonSdkType
import com.jetbrains.python.sdk.*
import com.jetbrains.python.sdk.conda.PyCondaSdkCustomizer
import com.jetbrains.python.sdk.configuration.CreateSdkInfoWithTool
import com.jetbrains.python.sdk.configuration.PyProjectSdkConfiguration
import com.jetbrains.python.sdk.detectSystemWideSdks
import com.jetbrains.python.sdk.detectVirtualEnvs
import com.jetbrains.python.sdk.filterAssociatedSdks
import com.jetbrains.python.sdk.filterSharedCondaEnvs
import com.jetbrains.python.sdk.filterSystemWideSdks
import com.jetbrains.python.sdk.guessedLanguageLevel
import com.jetbrains.python.sdk.configuration.PyProjectSdkConfigurationExtension
import com.jetbrains.python.sdk.legacy.PythonSdkUtil
import com.jetbrains.python.sdk.mostPreferred
import com.jetbrains.python.sdk.setupSdkLaunch
import com.jetbrains.python.ui.PyUiUtil
import one.util.streamex.StreamEx
import java.io.File
import java.util.function.Function
import java.util.regex.Matcher
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch
import java.util.regex.Pattern
private val NAME: Pattern = Pattern.compile("Python (?<version>\\d\\.\\d+)\\s*(\\((?<name>.+?)\\))?")
class PyInterpreterInspection : PyInspection() {
override fun buildVisitor(
holder: ProblemsHolder,
isOnTheFly: Boolean,
session: LocalInspectionToolSession
): PsiElementVisitor {
return Visitor(holder, PyInspectionVisitor.getContext(session))
}
override fun buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean, session: LocalInspectionToolSession): PsiElementVisitor =
PyInterpreterInspectionVisitor(holder, PyInspectionVisitor.getContext(session))
}
class Visitor(
holder: ProblemsHolder?,
context: TypeEvalContext
) : PyInspectionVisitor(holder, context) {
override fun visitPyFile(node: PyFile) {
if (isFileIgnored(node)) return
val module = ModuleUtilCore.findModuleForPsiElement(node)
val sdk = PyBuiltinCache.Companion.findSdkForFile(node)
val pyCharm = PythonIdeLanguageCustomization.isMainlyPythonIde()
class PyInterpreterInspectionVisitor(
holder: ProblemsHolder?,
context: TypeEvalContext,
) : PyInspectionVisitor(holder, context) {
val fixes: MutableList<LocalQuickFix?> = ArrayList<LocalQuickFix?>()
if (sdk == null) {
val message: @InspectionMessage String
if (pyCharm) {
message = PyPsiBundle.message("INSP.interpreter.no.python.interpreter.configured.for.project")
}
else {
message = PyPsiBundle.message("INSP.interpreter.no.python.interpreter.configured.for.module")
}
registerProblemWithCommonFixes(node, message, module, fixes, pyCharm)
}
}
override fun visitPyFile(node: PyFile) {
if (isFileIgnored(node)) return
val module = ModuleUtilCore.findModuleForPsiElement(node)
val sdk = PyBuiltinCache.findSdkForFile(node)
val pyCharm = PythonIdeLanguageCustomization.isMainlyPythonIde()
private fun registerProblemWithCommonFixes(
node: PyFile,
@InspectionMessage message: @InspectionMessage String,
module: Module?,
fixes: MutableList<LocalQuickFix?>,
pyCharm: Boolean
) {
if (module != null && pyCharm) {
val sdkName = ProjectRootManager.getInstance(node.getProject()).getProjectSdkName()
ContainerUtil.addIfNotNull<LocalQuickFix?>(fixes, getSuitableSdkFix(sdkName, module))
}
if (module != null && pyCharm) {
fixes.add(ConfigureInterpreterFix())
if (sdk == null) {
val message = if (pyCharm) {
PyPsiBundle.message("INSP.interpreter.no.python.interpreter.configured.for.project")
}
else {
fixes.add(InterpreterSettingsQuickFix(module))
PyPsiBundle.message("INSP.interpreter.no.python.interpreter.configured.for.module")
}
registerProblemWithCommonFixes(node, message, module, pyCharm)
}
}
registerProblem(node, message, *fixes.toArray<LocalQuickFix?>(LocalQuickFix.EMPTY_ARRAY))
private fun registerProblemWithCommonFixes(node: PyFile, @InspectionMessage message: String, module: Module?, pyCharm: Boolean) {
val fixes = buildList {
if (module != null && pyCharm) {
val sdkName = ProjectRootManager.getInstance(node.project).projectSdkName
getSuitableSdkFix(sdkName, module)?.let { add(it) }
add(ConfigureInterpreterFix())
}
else {
add(InterpreterSettingsQuickFix(module))
}
}
companion object {
private fun getSuitableSdkFix(name: String?, module: Module): LocalQuickFix? {
// this method is based on com.jetbrains.python.sdk.PySdkExtKt.suggestAssociatedSdkName
// please keep it in sync with the mentioned method and com.jetbrains.python.PythonSdkConfigurator.configureSdk
registerProblem(node, message, *fixes.toTypedArray())
}
}
val existingSdks: List<Sdk> = existingSdks
private fun getSuitableSdkFix(name: String?, module: Module): LocalQuickFix? {
// this method is based on com.jetbrains.python.sdk.PySdkExtKt.suggestAssociatedSdkName
// please keep it in sync with the mentioned method and com.jetbrains.python.PythonSdkConfigurator.configureSdk
val associatedSdk = mostPreferred(filterAssociatedSdks(module, existingSdks))
if (associatedSdk != null) return UseExistingInterpreterFix(associatedSdk, module)
val existingSdks = getExistingSdks()
val context = UserDataHolderBase()
val associatedSdk = mostPreferred(filterAssociatedSdks(module, existingSdks))
if (associatedSdk != null) return UseExistingInterpreterFix(associatedSdk, module)
val createSdkInfos: List<CreateSdkInfoWithTool> = findAllSortedForModuleForJvm(module)
if (!createSdkInfos.isEmpty()) {
return UseProvidedInterpreterFix(module, createSdkInfos.first())
val context = UserDataHolderBase()
val createSdkInfo = runBlockingMaybeCancellable {
PyProjectSdkConfigurationExtension.findAllSortedForModule(module).firstOrNull()
}
if (createSdkInfo != null) return UseProvidedInterpreterFix(module, createSdkInfo)
if (name != null) {
val matcher = NAME.matcher(name)
if (matcher.matches()) {
val venvName = matcher.group("name")
if (venvName != null) {
val detectedAssociatedViaRootNameEnv = detectAssociatedViaRootNameEnv(venvName, module, existingSdks, context)
if (detectedAssociatedViaRootNameEnv != null) {
return UseDetectedInterpreterFix(detectedAssociatedViaRootNameEnv, existingSdks, true, module)
}
if (name != null) {
val matcher: Matcher = NAME.matcher(name)
if (matcher.matches()) {
val venvName = matcher.group("name")
if (venvName != null) {
val detectedAssociatedViaRootNameEnv: PyDetectedSdk? = detectAssociatedViaRootNameEnv(venvName, module, existingSdks, context)
if (detectedAssociatedViaRootNameEnv != null) {
return UseDetectedInterpreterFix(detectedAssociatedViaRootNameEnv, existingSdks, true, module)
}
}
else {
val detectedSystemWideSdk: PyDetectedSdk? = detectSystemWideSdk(matcher.group("version"), module, existingSdks, context)
if (detectedSystemWideSdk != null) {
return UseDetectedInterpreterFix(detectedSystemWideSdk, existingSdks, false, module)
}
}
}
}
if (PyCondaSdkCustomizer.Companion.instance.suggestSharedCondaEnvironments) {
val sharedCondaEnv = mostPreferred(filterSharedCondaEnvs(module, existingSdks))
if (sharedCondaEnv != null) {
return UseExistingInterpreterFix(sharedCondaEnv, module)
}
}
// TODO: We should use SystemPythonService here as well, postponing as it's quite unlikely we get here (although we can)
val systemWideSdk = mostPreferred(filterSystemWideSdks(existingSdks))
if (systemWideSdk != null) {
return UseExistingInterpreterFix(systemWideSdk, module)
}
val configurator = PyCondaSdkCustomizer.Companion.instance.fallbackConfigurator
if (configurator != null) {
val fallbackCreateSdkInfo =
PyCondaSdkCustomizer.Companion.checkEnvironmentAndPrepareSdkCreatorBlocking(configurator, module)
if (fallbackCreateSdkInfo != null) {
return UseProvidedInterpreterFix(module, fallbackCreateSdkInfo)
}
}
val detectedSystemWideSdk = ContainerUtil.getFirstItem<PyDetectedSdk>(detectSystemWideSdks(module, existingSdks))
}
else {
val detectedSystemWideSdk = detectSystemWideSdk(matcher.group("version"), module, existingSdks, context)
if (detectedSystemWideSdk != null) {
return UseDetectedInterpreterFix(detectedSystemWideSdk, existingSdks, false, module)
}
return null
}
private val existingSdks: List<Sdk>
get() {
val model = ProjectSdksModel()
model.reset(null)
return ContainerUtil.filter(model.getSdks(),
Condition { it.getSdkType() is PythonSdkType })
}
private fun detectAssociatedViaRootNameEnv(
associatedName: String,
module: Module,
existingSdks: List<Sdk>,
context: UserDataHolderBase
): PyDetectedSdk? {
return Companion.findAssociatedViaRootNameEnv(
associatedName,
detectVirtualEnvs(module, existingSdks, context),
Function { sdk: PyDetectedSdk? -> getVirtualEnvRootName(sdk!!) }
)
}
private fun detectSystemWideSdk(
version: String,
module: Module,
existingSdks: List<Sdk>,
context: UserDataHolderBase
): PyDetectedSdk? {
val parsedVersion: LanguageLevel = LanguageLevel.fromPythonVersion(version)!!
if (parsedVersion.toString() == version) {
return ContainerUtil.find<PyDetectedSdk>(
detectSystemWideSdks(module, existingSdks, context),
Condition { sdk: PyDetectedSdk -> sdk.guessedLanguageLevel == parsedVersion }
)
}
return null
}
private fun findAssociatedViaRootNameEnv(
associatedName: String,
envs: List<PyDetectedSdk>,
envRootName: Function<PyDetectedSdk?, String?>
): PyDetectedSdk? {
return StreamEx
.of(envs)
.filter { sdk: PyDetectedSdk -> associatedName == envRootName.apply(sdk) }
.max(compareBy<PyDetectedSdk> { it.guessedLanguageLevel }.thenBy { it.homePath })
.orElse(null)
}
private fun getVirtualEnvRootName(sdk: PyDetectedSdk): String? {
val path = sdk.getHomePath()
return if (path == null) null else getEnvRootName(PythonSdkUtil.getVirtualEnvRoot(path))
}
private fun getEnvRootName(envRoot: File?): String? {
return if (envRoot == null) null else PathUtil.getFileName(envRoot.getPath())
}
}
}
class ConfigureInterpreterFix : LocalQuickFix {
@IntentionFamilyName
override fun getFamilyName(): @IntentionFamilyName String {
return PyPsiBundle.message("INSP.interpreter.configure.python.interpreter")
if (PyCondaSdkCustomizer.instance.suggestSharedCondaEnvironments) {
val sharedCondaEnv = mostPreferred(filterSharedCondaEnvs(module, existingSdks))
if (sharedCondaEnv != null) return UseExistingInterpreterFix(sharedCondaEnv, module)
}
// TODO: We should use SystemPythonService here as well, postponing as it's quite unlikely we get here (although we can)
val systemWideSdk = mostPreferred(filterSystemWideSdks(existingSdks))
if (systemWideSdk != null) return UseExistingInterpreterFix(systemWideSdk, module)
val configurator = PyCondaSdkCustomizer.instance.fallbackConfigurator
if (configurator != null) {
val fallbackCreateSdkInfo = PyCondaSdkCustomizer.checkEnvironmentAndPrepareSdkCreatorBlocking(configurator, module)
if (fallbackCreateSdkInfo != null) return UseProvidedInterpreterFix(module, fallbackCreateSdkInfo)
}
val detectedSystemWideSdk = detectSystemWideSdks(module, existingSdks).firstOrNull()
if (detectedSystemWideSdk != null) return UseDetectedInterpreterFix(detectedSystemWideSdk, existingSdks, false, module)
return null
}
private fun getExistingSdks(): List<Sdk> {
val model = ProjectSdksModel()
model.reset(null)
return model.sdks.filter { it.sdkType is PythonSdkType }
}
private fun detectAssociatedViaRootNameEnv(
associatedName: String, module: Module, existingSdks: List<Sdk>, context: UserDataHolderBase,
): PyDetectedSdk? = findAssociatedViaRootNameEnv(associatedName, detectVirtualEnvs(module, existingSdks, context))
private fun detectSystemWideSdk(version: String, module: Module, existingSdks: List<Sdk>, context: UserDataHolderBase): PyDetectedSdk? {
val parsedVersion = LanguageLevel.fromPythonVersion(version)!!
return if (parsedVersion.toString() == version) {
detectSystemWideSdks(module, existingSdks, context).firstOrNull { it.guessedLanguageLevel == parsedVersion }
}
else null
}
private fun findAssociatedViaRootNameEnv(associatedName: String, envs: List<PyDetectedSdk>): PyDetectedSdk? =
envs.filter { associatedName == getVirtualEnvRootName(it) }
.maxWithOrNull(compareBy<PyDetectedSdk> { it.guessedLanguageLevel }.thenBy { it.homePath })
private fun getVirtualEnvRootName(sdk: PyDetectedSdk): String? {
val file = sdk.homePath?.let { PythonSdkUtil.getVirtualEnvRoot(it) } ?: return null
return PathUtil.getFileName(file.path)
}
private fun isFileIgnored(pyFile: PyFile): Boolean =
PyInspectionExtension.EP_NAME.extensionList.any { it.ignoreInterpreterWarnings(pyFile) }
class ConfigureInterpreterFix : LocalQuickFix {
@IntentionFamilyName
override fun getFamilyName(): String = PyPsiBundle.message("INSP.interpreter.configure.python.interpreter")
override fun startInWriteAction(): Boolean = false
override fun applyFix(project: Project, descriptor: ProblemDescriptor) {
val element = descriptor.psiElement ?: return
val module = ModuleUtilCore.findModuleForPsiElement(element) ?: return
PySdkPopupFactory.createAndShow(module)
}
}
private class UseProvidedInterpreterFix(private val myModule: Module, private val myCreateSdkInfo: CreateSdkInfoWithTool) : LocalQuickFix {
@IntentionFamilyName
override fun getFamilyName(): String = PyPsiBundle.message("INSP.interpreter.use.suggested.interpreter")
@IntentionName
override fun getName(): String = myCreateSdkInfo.createSdkInfo.intentionName
override fun applyFix(project: Project, descriptor: ProblemDescriptor) {
if (!enableSDKAutoConfigurator) {
return PyProjectSdkConfiguration.configureSdkUsingCreateSdkInfo(myModule, myCreateSdkInfo)
}
override fun startInWriteAction(): Boolean {
return false
}
override fun applyFix(project: Project, descriptor: ProblemDescriptor) {
val element = descriptor.getPsiElement()
if (element == null) return
val module = ModuleUtilCore.findModuleForPsiElement(element)
if (module == null) return
PySdkPopupFactory.Companion.createAndShow(module)
project.service<MyService>().scope.launch {
detectSdkForModulesIn(project)
}
}
private class UseProvidedInterpreterFix(
private val myModule: Module,
private val myCreateSdkInfo: CreateSdkInfoWithTool
) : LocalQuickFix {
@IntentionFamilyName
override fun getFamilyName(): @IntentionFamilyName String {
return PyPsiBundle.message("INSP.interpreter.use.suggested.interpreter")
}
override fun generatePreview(project: Project, previewDescriptor: ProblemDescriptor): IntentionPreviewInfo {
// The quick fix doesn't change the code and is suggested on a file level
return IntentionPreviewInfo.EMPTY
}
}
@IntentionName
override fun getName(): @IntentionName String {
return myCreateSdkInfo.createSdkInfo.intentionName
}
private abstract class UseInterpreterFix<T : Sdk>(protected val mySdk: T) : LocalQuickFix {
@IntentionFamilyName
override fun getFamilyName(): String = PyPsiBundle.message("INSP.interpreter.use.suggested.interpreter")
override fun applyFix(project: Project, descriptor: ProblemDescriptor) {
if (!detectSdkForModulesForJvmIn(project)) {
PyProjectSdkConfiguration.configureSdkUsingCreateSdkInfo(myModule, myCreateSdkInfo)
}
}
@IntentionName
override fun getName(): String = PyPsiBundle.message("INSP.interpreter.use.interpreter", PySdkPopupFactory.shortenNameInPopup(mySdk, 75))
override fun generatePreview(project: Project, previewDescriptor: ProblemDescriptor): IntentionPreviewInfo {
// The quick fix doesn't change the code and is suggested on a file level
return IntentionPreviewInfo.EMPTY
override fun startInWriteAction(): Boolean = false
}
private class UseExistingInterpreterFix(existingSdk: Sdk, private val myModule: Module) : UseInterpreterFix<Sdk>(existingSdk) {
override fun applyFix(project: Project, descriptor: ProblemDescriptor) {
PyUiUtil.clearFileLevelInspectionResults(descriptor.psiElement.containingFile)
project.service<MyService>().scope.launch {
PyProjectSdkConfiguration.setReadyToUseSdk(project, myModule, mySdk)
}
}
}
private abstract class UseInterpreterFix<T : Sdk> protected constructor(protected val mySdk: T) : LocalQuickFix {
@IntentionFamilyName
override fun getFamilyName(): @IntentionFamilyName String {
return PyPsiBundle.message("INSP.interpreter.use.suggested.interpreter")
}
@IntentionName
override fun getName(): @IntentionName String {
return PyPsiBundle.message("INSP.interpreter.use.interpreter", PySdkPopupFactory.Companion.shortenNameInPopup(mySdk!!, 75))
}
override fun startInWriteAction(): Boolean {
return false
private class UseDetectedInterpreterFix(
detectedSdk: PyDetectedSdk,
private val myExistingSdks: List<Sdk>,
private val doAssociate: Boolean,
private val myModule: Module,
) : UseInterpreterFix<PyDetectedSdk>(detectedSdk) {
override fun applyFix(project: Project, descriptor: ProblemDescriptor) {
PyUiUtil.clearFileLevelInspectionResults(descriptor.psiElement.containingFile)
project.service<MyService>().scope.launch {
mySdk.setupSdk(myModule, myExistingSdks, doAssociate)
}
}
}
private class UseExistingInterpreterFix(existingSdk: Sdk, private val myModule: Module) : UseInterpreterFix<Sdk>(existingSdk) {
override fun applyFix(project: Project, descriptor: ProblemDescriptor) {
PyUiUtil.clearFileLevelInspectionResults(descriptor.getPsiElement().getContainingFile())
ApplicationManager.getApplication().executeOnPooledThread(
Runnable {
PyProjectSdkConfiguration.setReadyToUseSdkSync(project, myModule, mySdk)
})
}
}
private class UseDetectedInterpreterFix(
detectedSdk: PyDetectedSdk,
private val myExistingSdks: List<Sdk>,
private val doAssociate: Boolean,
private val myModule: Module
) : UseInterpreterFix<PyDetectedSdk>(detectedSdk) {
override fun applyFix(project: Project, descriptor: ProblemDescriptor) {
PyUiUtil.clearFileLevelInspectionResults(descriptor.getPsiElement().getContainingFile())
mySdk.setupSdkLaunch(myModule, myExistingSdks, doAssociate)
}
}
companion object {
private val NAME: Pattern = Pattern.compile("Python (?<version>\\d\\.\\d+)\\s*(\\((?<name>.+?)\\))?")
private fun isFileIgnored(pyFile: PyFile): Boolean {
return PyInspectionExtension.EP_NAME.extensionList.stream().anyMatch { ep: PyInspectionExtension? ->
ep!!.ignoreInterpreterWarnings(pyFile)
}
}
}
}
@Service(Service.Level.PROJECT)
private class MyService(val scope: CoroutineScope)
@@ -1,42 +0,0 @@
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.jetbrains.python.inspections.interpreter
import com.intellij.openapi.components.Service
import com.intellij.openapi.components.service
import com.intellij.openapi.module.Module
import com.intellij.openapi.progress.runBlockingMaybeCancellable
import com.intellij.openapi.project.Project
import com.intellij.python.sdkConfigurator.common.detectSdkForModulesIn
import com.intellij.python.sdkConfigurator.common.enableSDKAutoConfigurator
import com.intellij.util.concurrency.annotations.RequiresBackgroundThread
import com.jetbrains.python.sdk.configuration.CreateSdkInfoWithTool
import com.jetbrains.python.sdk.configuration.PyProjectSdkConfigurationExtension
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch
import org.jetbrains.annotations.ApiStatus
/**
* To be used by [PyInterpreterInspection] only
*/
@ApiStatus.Internal
internal fun detectSdkForModulesForJvmIn(project: Project): Boolean {
if (!enableSDKAutoConfigurator) {
return false
}
project.service<MyService>().scope.launch {
detectSdkForModulesIn(project)
}
return true
}
@Service(Service.Level.PROJECT)
private class MyService(val scope: CoroutineScope)
/**
* To be used by [PyInterpreterInspection] only
*/
@ApiStatus.Internal
@RequiresBackgroundThread
internal fun findAllSortedForModuleForJvm(module: Module): List<CreateSdkInfoWithTool> = runBlockingMaybeCancellable {
PyProjectSdkConfigurationExtension.findAllSortedForModule(module)
}