PY-85634 Move InterpreterSettingsQuickFix to a separate file

Follow-up to IJ-MR-178613

GitOrigin-RevId: 19520730af0b9df85c5b98baf36de6902b5701c8
This commit is contained in:
Alexey Katsman
2025-11-25 18:47:50 +00:00
committed by intellij-monorepo-bot
parent 10e67083be
commit 93a8360b34
7 changed files with 84 additions and 68 deletions
@@ -19,17 +19,17 @@ import com.intellij.util.concurrency.annotations.RequiresEdt
import com.intellij.util.concurrency.annotations.RequiresReadLock
import com.intellij.util.ui.FormBuilder
import com.jetbrains.python.PyBundle
import com.jetbrains.python.sdk.impl.PySdkBundle
import com.jetbrains.python.Result
import com.jetbrains.python.configuration.PyConfigurableInterpreterList
import com.jetbrains.python.errorProcessing.ErrorSink
import com.jetbrains.python.errorProcessing.emit
import com.jetbrains.python.inspections.interpreter.PyInterpreterInspection
import com.jetbrains.python.inspections.interpreter.InterpreterSettingsQuickFix
import com.jetbrains.python.projectCreation.createVenvAndSdk
import com.jetbrains.python.sdk.PySdkToInstall
import com.jetbrains.python.sdk.add.PySdkPathChoosingComboBox
import com.jetbrains.python.sdk.add.addBaseInterpretersAsync
import com.jetbrains.python.sdk.findBaseSdks
import com.jetbrains.python.sdk.impl.PySdkBundle
import com.jetbrains.python.sdk.pythonSdk
import com.jetbrains.python.statistics.modules
import com.jetbrains.python.util.ShowingMessageErrorSync
@@ -175,7 +175,7 @@ internal class PythonLangSupport(private val errorSink: ErrorSink = ShowingMessa
}
val configureCallbackId = LearningUiManager.addCallback {
val module = project.modules.singleOrNull()
PyInterpreterInspection.InterpreterSettingsQuickFix.showPythonInterpreterSettings(project, module)
InterpreterSettingsQuickFix.showPythonInterpreterSettings(project, module)
}
if (useUserProjects || isLearningProject(project, primaryLanguage)) {
showWarning(PythonLessonsBundle.message("no.interpreter.in.learning.project", configureCallbackId),
@@ -7,7 +7,7 @@ import com.intellij.openapi.util.NlsSafe
import com.intellij.openapi.util.UserDataHolderBase
import com.intellij.ui.dsl.builder.Panel
import com.jetbrains.python.configuration.PyConfigurableInterpreterList
import com.jetbrains.python.inspections.interpreter.PyInterpreterInspection
import com.jetbrains.python.inspections.interpreter.InterpreterSettingsQuickFix
import com.jetbrains.python.sdk.findBaseSdks
import com.jetbrains.python.sdk.flavors.PythonSdkFlavor
import com.jetbrains.python.sdk.pythonSdk
@@ -33,7 +33,7 @@ object PythonLessonsUtil {
fun LessonContext.showWarningIfPython3NotFound() {
task {
val callbackId = LearningUiManager.addCallback {
PyInterpreterInspection.InterpreterSettingsQuickFix.showPythonInterpreterSettings(project, project.modules.first())
InterpreterSettingsQuickFix.showPythonInterpreterSettings(project, project.modules.first())
}
stateCheck { isPython3Installed(project) }
showWarning(PythonLessonsBundle.message("python.3.required.warning.message", callbackId)) {
@@ -42,13 +42,15 @@ object PythonLessonsUtil {
}
}
fun prepareFeedbackDataForOnboardingLesson(project: Project,
configPropertyName: String,
reportTitle: String,
feedbackReportId: String,
primaryLanguage: LangSupport,
lessonEndInfo: LessonEndInfo,
usedInterpreterAtStart: String) {
fun prepareFeedbackDataForOnboardingLesson(
project: Project,
configPropertyName: String,
reportTitle: String,
feedbackReportId: String,
primaryLanguage: LangSupport,
lessonEndInfo: LessonEndInfo,
usedInterpreterAtStart: String,
) {
if (!shouldCollectFeedbackResults()) {
return
}
@@ -68,6 +70,7 @@ object PythonLessonsUtil {
}
val usedInterpreter = project.pythonSdk?.versionString ?: "none"
@Suppress("HardCodedStringLiteral", "DialogTitleCapitalization") // a very strange warning report here
val startInterpreter = if (usedInterpreterAtStart == usedInterpreter) "same" else usedInterpreterAtStart
@@ -16,7 +16,7 @@ import org.jetbrains.annotations.NotNull;
/**
* User : ktisha
*
* <p>
* filter out some python inspections and annotations if we're in docstring substitution
*/
public final class PyDocstringVisitorFilter implements PythonVisitorFilter {
@@ -31,13 +31,17 @@ public final class PyDocstringVisitorFilter implements PythonVisitorFilter {
visitorClass == PyByteLiteralInspection.class || visitorClass == PyNonAsciiCharInspection.class ||
visitorClass == PyPackageRequirementsInspection.class || visitorClass == PyMandatoryEncodingInspection.class ||
visitorClass == PyInterpreterInspection.class || visitorClass == PyDocstringTypesInspection.class ||
visitorClass == PySingleQuotedDocstringInspection.class || visitorClass == PyClassHasNoInitInspection.class ||
visitorClass == PySingleQuotedDocstringInspection.class || visitorClass == PyClassHasNoInitInspection.class ||
visitorClass == PyStatementEffectInspection.class || visitorClass == PyPep8Inspection.class) {
return false;
}
//annotators
if (visitorClass == PyDocStringHighlightingAnnotator.class || visitorClass == PyParameterListAnnotatorVisitor.class || visitorClass == PyReturnYieldAnnotatorVisitor.class || visitorClass == PyFunctionHighlightingAnnotator.class)
if (visitorClass == PyDocStringHighlightingAnnotator.class ||
visitorClass == PyParameterListAnnotatorVisitor.class ||
visitorClass == PyReturnYieldAnnotatorVisitor.class ||
visitorClass == PyFunctionHighlightingAnnotator.class) {
return false;
}
// doctest in separate file
final PsiFile topLevelFile = InjectedLanguageManager.getInstance(file.getProject()).getTopLevelFile(file);
if (visitorClass == PyUnresolvedReferencesInspection.class && !(topLevelFile instanceof PyFile)) {
@@ -0,0 +1,58 @@
// 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.codeInspection.LocalQuickFix
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
import com.intellij.openapi.roots.ModuleRootManager
import com.intellij.openapi.roots.ProjectRootManager
import com.intellij.openapi.roots.ui.configuration.ProjectSettingsService
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 startInWriteAction(): Boolean {
return false
}
override fun applyFix(project: Project, descriptor: ProblemDescriptor) {
showPythonInterpreterSettings(project, myModule)
}
companion object {
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)
return
}
val settingsService = ProjectSettingsService.getInstance(project)
if (module == null || justOneModuleInheritingSdk(project, module)) {
settingsService.openProjectSettings()
}
else {
settingsService.openModuleSettings(module)
}
}
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
}
}
}
@@ -9,25 +9,17 @@ 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.ide.actions.ShowSettingsUtilImpl
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.module.Module
import com.intellij.openapi.module.ModuleManager
import com.intellij.openapi.module.ModuleUtilCore
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
import com.intellij.openapi.projectRoots.Sdk
import com.intellij.openapi.roots.ModuleRootManager
import com.intellij.openapi.roots.ProjectRootManager
import com.intellij.openapi.roots.ui.configuration.ProjectSettingsService
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.util.PathUtil
import com.intellij.util.PlatformUtils
import com.intellij.util.containers.ContainerUtil
import com.intellij.util.containers.toArray
import com.jetbrains.python.PyPsiBundle
@@ -243,47 +235,6 @@ class PyInterpreterInspection : PyInspection() {
}
}
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 startInWriteAction(): Boolean {
return false
}
override fun applyFix(project: Project, descriptor: ProblemDescriptor) {
showPythonInterpreterSettings(project, myModule)
}
companion object {
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)
return
}
val settingsService = ProjectSettingsService.getInstance(project)
if (module == null || justOneModuleInheritingSdk(project, module)) {
settingsService.openProjectSettings()
}
else {
settingsService.openModuleSettings(module)
}
}
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
}
}
}
class ConfigureInterpreterFix : LocalQuickFix {
@IntentionFamilyName
override fun getFamilyName(): @IntentionFamilyName String {
@@ -28,7 +28,7 @@ import com.intellij.ui.SimpleTextAttributes
import com.intellij.util.asDisposable
import com.jetbrains.python.PyBundle.message
import com.jetbrains.python.TraceContext
import com.jetbrains.python.inspections.interpreter.PyInterpreterInspection
import com.jetbrains.python.inspections.interpreter.InterpreterSettingsQuickFix
import com.jetbrains.python.packaging.toolwindow.details.PyPackageInfoPanel
import com.jetbrains.python.packaging.toolwindow.model.DisplayablePackage
import com.jetbrains.python.packaging.toolwindow.model.ErrorNode
@@ -93,7 +93,7 @@ class PyPackagingToolWindowPanel(private val project: Project) : SimpleToolWindo
@Suppress("DialogTitleCapitalization")
emptyText.appendLine(message("python.sdk.popup.interpreter.settings"), SimpleTextAttributes.LINK_ATTRIBUTES, object : ActionListener {
override fun actionPerformed(e: ActionEvent?) {
PyInterpreterInspection.InterpreterSettingsQuickFix.showPythonInterpreterSettings(project, null)
InterpreterSettingsQuickFix.showPythonInterpreterSettings(project, null)
}
})
}
@@ -16,7 +16,7 @@ import com.intellij.util.text.trimMiddle
import com.intellij.util.ui.SwingHelper
import com.jetbrains.python.PyBundle
import com.jetbrains.python.configuration.PyConfigurableInterpreterList
import com.jetbrains.python.inspections.interpreter.PyInterpreterInspection
import com.jetbrains.python.inspections.interpreter.InterpreterSettingsQuickFix
import com.jetbrains.python.psi.LanguageLevel
import com.jetbrains.python.run.PythonInterpreterTargetEnvironmentFactory
import com.jetbrains.python.run.codeCouldProbablyBeRunWithConfig
@@ -127,7 +127,7 @@ class PySdkPopupFactory(val module: Module) {
private inner class InterpreterSettingsAction : DumbAwareAction(PyBundle.messagePointer("python.sdk.popup.interpreter.settings")) {
override fun actionPerformed(e: AnActionEvent) {
PyInterpreterInspection.InterpreterSettingsQuickFix.showPythonInterpreterSettings(module.project, module)
InterpreterSettingsQuickFix.showPythonInterpreterSettings(module.project, module)
}
}
}