PY-76416: Filter out venvs from base pythons in SDK creation dialog.

Base Pythons are system-wide pythons, not venvs.
`PythonSdkFlavor.isPlatformIndependent` is `false` for base pythons.

Venvs can only be created on top of base pythons and not on top of other venvs.

We detect all pythons (even venvs in `~/.virtualenvs` e.t.c.) because we might need them in "Select Existing Interpreter" window, but since for "Create New Venv" we can only use base pythons, we use flavor to filter.


(cherry picked from commit 7b4719b821243a4d97304cfa1d106439b11f63b1)

KT-MR-18675

GitOrigin-RevId: e001e8f593b7a964067cbd04fcc3fd22ea8ec4a2
This commit is contained in:
Ilya.Kazakevich
2024-10-28 21:34:36 +01:00
committed by intellij-monorepo-bot
parent 12357b95f7
commit 81cdb86823

View File

@@ -4,7 +4,6 @@ package com.jetbrains.python.sdk.add.v2
import com.intellij.execution.target.TargetEnvironmentConfiguration
import com.intellij.ide.util.PropertiesComponent
import com.intellij.openapi.application.EDT
import com.intellij.openapi.application.ModalityState
import com.intellij.openapi.diagnostic.getOrLogException
import com.intellij.openapi.fileChooser.FileChooser
import com.intellij.openapi.observable.properties.ObservableMutableProperty
@@ -26,8 +25,11 @@ import com.jetbrains.python.sdk.flavors.conda.PyCondaEnvIdentity
import com.jetbrains.python.sdk.pipenv.pipEnvPath
import com.jetbrains.python.sdk.poetry.poetryPath
import com.jetbrains.python.util.ErrorSink
import kotlinx.coroutines.*
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.*
import kotlinx.coroutines.plus
import kotlinx.coroutines.withContext
import java.nio.file.Path
import kotlin.io.path.pathString
@@ -61,6 +63,7 @@ abstract class PythonAddInterpreterModel(params: PyInterpreterModelParams) {
.stateIn(scope + uiContext, started = SharingStarted.Eagerly, initialValue = emptyList())
val baseInterpreters: StateFlow<List<PythonSelectableInterpreter>> = allInterpreters
.map { it.filter { it.isBasePython() } }
.mapLatest {
it.filter { it !is ExistingSelectableInterpreter || it.isSystemWide } + installable
}
@@ -229,8 +232,15 @@ class PythonLocalAddInterpreterModel(params: PyInterpreterModelParams)
}
// todo does it need target configuration
sealed class PythonSelectableInterpreter {
/**
* Base python is some system python (not venv) which can be used as a base for venv.
* In terms of flavors we call it __not__ [PythonSdkFlavor.isPlatformIndependent]
*/
open suspend fun isBasePython(): Boolean = withContext(Dispatchers.IO) {
PythonSdkFlavor.tryDetectFlavorByLocalPath(homePath)?.isPlatformIndependent == false
}
abstract val homePath: String
abstract val languageLevel: LanguageLevel
override fun toString(): String =
@@ -238,6 +248,10 @@ sealed class PythonSelectableInterpreter {
}
class ExistingSelectableInterpreter(val sdk: Sdk, override val languageLevel: LanguageLevel, val isSystemWide: Boolean) : PythonSelectableInterpreter() {
override suspend fun isBasePython(): Boolean = withContext(Dispatchers.IO) {
!sdk.sdkFlavor.isPlatformIndependent
}
override val homePath = sdk.homePath!! // todo is it safe
}
@@ -246,6 +260,7 @@ class DetectedSelectableInterpreter(override val homePath: String, override val
class ManuallyAddedSelectableInterpreter(override val homePath: String, override val languageLevel: LanguageLevel) : PythonSelectableInterpreter()
class InstallableSelectableInterpreter(val sdk: PySdkToInstall) : PythonSelectableInterpreter() {
override suspend fun isBasePython(): Boolean = true
override val homePath: String = ""
override val languageLevel = PySdkUtil.getLanguageLevelForSdk(sdk)
}