Python: make python with language level independent from python binary to support conda and other python types.

GitOrigin-RevId: 2752eed732ab6d3e45da38714106700ba2014bd8
This commit is contained in:
Ilya.Kazakevich
2025-06-07 07:00:33 +02:00
committed by intellij-monorepo-bot
parent 2e14347844
commit cea3e7d9c0
19 changed files with 107 additions and 52 deletions

View File

@@ -6,8 +6,9 @@ import com.intellij.openapi.project.Project
import com.intellij.openapi.project.ProjectManager
import com.intellij.openapi.projectRoots.ProjectJdkTable
import com.intellij.openapi.util.SystemInfoRt
import com.intellij.python.community.impl.venv.createVenv
import com.intellij.python.community.services.internal.impl.PythonWithLanguageLevelImpl
import com.intellij.python.community.services.internal.impl.VanillaPythonWithLanguageLevelImpl
import com.intellij.python.community.services.systemPython.SystemPythonService
import com.intellij.python.community.services.systemPython.createVenvFromSystemPython
import com.intellij.python.featuresTrainer.ift.PythonLangSupport
import com.intellij.python.junit5Tests.framework.env.PyEnvTestCase
import com.intellij.python.junit5Tests.framework.env.PythonBinaryPath
@@ -15,6 +16,7 @@ import com.intellij.python.junit5Tests.framework.winLockedFile.deleteCheckLockin
import com.intellij.testFramework.common.timeoutRunBlocking
import com.jetbrains.python.PythonBinary
import com.jetbrains.python.errorProcessing.ErrorSink
import com.jetbrains.python.getOrThrow
import com.jetbrains.python.sdk.pythonSdk
import com.jetbrains.python.venvReader.VirtualEnvReader.Companion.DEFAULT_VIRTUALENV_DIRNAME
import kotlinx.coroutines.CompletableDeferred
@@ -54,7 +56,8 @@ class PythonLangSupportTest {
@ParameterizedTest
@ValueSource(booleans = [true, false])
fun ensureVenvCreatedTest(venvAlreadyExists: Boolean, @PythonBinaryPath python: PythonBinary): Unit = timeoutRunBlocking(10.minutes) {
fun ensureVenvCreatedTest(venvAlreadyExists: Boolean, @PythonBinaryPath pythonBinary: PythonBinary): Unit = timeoutRunBlocking(10.minutes) {
val python = SystemPythonService().registerSystemPython(pythonBinary).getOrThrow()
val learningProjectsPath = ProjectUtils.learningProjectsPath
assert(learningProjectsPath.startsWith(temporarySystemPath)) { "$learningProjectsPath must reside in $temporarySystemPath" }
@@ -64,7 +67,7 @@ class PythonLangSupportTest {
if (venvAlreadyExists) {
val venvPath = learningProjectsPath.resolve(DEFAULT_VIRTUALENV_DIRNAME)
createVenv(python, venvPath).orThrow()
createVenvFromSystemPython(python, venvPath).orThrow()
}
val sema = CompletableDeferred<Project>()
@@ -81,7 +84,7 @@ class PythonLangSupportTest {
val sdk = project.pythonSdk!!
try {
val pythonBinary = Path.of(sdk.homePath!!)
Assertions.assertTrue(PythonWithLanguageLevelImpl.createByPythonBinary(pythonBinary).orThrow().languageLevel.isPy3K, "Sdk is broken")
Assertions.assertTrue(VanillaPythonWithLanguageLevelImpl.createByPythonBinary(pythonBinary).orThrow().languageLevel.isPy3K, "Sdk is broken")
}
finally {
writeAction {

View File

@@ -5,9 +5,10 @@ import com.intellij.platform.eel.EelPlatform
import com.intellij.platform.eel.provider.asNioPath
import com.intellij.platform.eel.provider.getEelDescriptor
import com.intellij.python.community.execService.python.validatePythonAndGetVersion
import com.intellij.python.community.services.internal.impl.PythonWithLanguageLevelImpl.Companion.concurrentLimit
import com.intellij.python.community.services.internal.impl.PythonWithLanguageLevelImpl.Companion.createByPythonBinary
import com.intellij.python.community.services.internal.impl.VanillaPythonWithLanguageLevelImpl.Companion.concurrentLimit
import com.intellij.python.community.services.internal.impl.VanillaPythonWithLanguageLevelImpl.Companion.createByPythonBinary
import com.intellij.python.community.services.shared.PythonWithLanguageLevel
import com.intellij.python.community.services.shared.VanillaPythonWithLanguageLevel
import com.jetbrains.python.PythonBinary
import com.jetbrains.python.Result
import com.jetbrains.python.errorProcessing.PyResult
@@ -23,10 +24,11 @@ import kotlin.io.path.pathString
import kotlin.io.path.relativeTo
@Internal
class PythonWithLanguageLevelImpl internal constructor(
class VanillaPythonWithLanguageLevelImpl internal constructor(
override val pythonBinary: PythonBinary,
override val languageLevel: LanguageLevel,
) : PythonWithLanguageLevel, Comparable<PythonWithLanguageLevel> {
) : VanillaPythonWithLanguageLevel {
companion object {
private val concurrentLimit = Semaphore(permits = 4)
@@ -35,7 +37,7 @@ class PythonWithLanguageLevelImpl internal constructor(
* Like [createByPythonBinary] but runs in parallel up to [concurrentLimit]
* @return python path -> python with language level sorted from highest to lowest.
*/
suspend fun createByPythonBinaries(pythonBinaries: Collection<PythonBinary>): Collection<Pair<PythonBinary, PyResult<PythonWithLanguageLevel>>> =
suspend fun createByPythonBinaries(pythonBinaries: Collection<PythonBinary>): Collection<Pair<PythonBinary, PyResult<VanillaPythonWithLanguageLevel>>> =
coroutineScope {
pythonBinaries.map {
async {
@@ -46,9 +48,9 @@ class PythonWithLanguageLevelImpl internal constructor(
}.awaitAll()
}.sortedBy { it.first }
suspend fun createByPythonBinary(pythonBinary: PythonBinary): PyResult<PythonWithLanguageLevelImpl> {
suspend fun createByPythonBinary(pythonBinary: PythonBinary): PyResult<VanillaPythonWithLanguageLevelImpl> {
val languageLevel = pythonBinary.validatePythonAndGetVersion().getOr { return it }
return Result.success(PythonWithLanguageLevelImpl(pythonBinary, languageLevel))
return Result.success(VanillaPythonWithLanguageLevelImpl(pythonBinary, languageLevel))
}
}
@@ -56,7 +58,7 @@ class PythonWithLanguageLevelImpl internal constructor(
if (this === other) return true
if (javaClass != other?.javaClass) return false
other as PythonWithLanguageLevelImpl
other as VanillaPythonWithLanguageLevelImpl
return pythonBinary == other.pythonBinary
}

View File

@@ -1,7 +1,7 @@
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.python.junit5Tests.env.services.internal.impl
import com.intellij.python.community.services.internal.impl.PythonWithLanguageLevelImpl
import com.intellij.python.community.services.internal.impl.VanillaPythonWithLanguageLevelImpl
import com.intellij.python.junit5Tests.framework.env.PyEnvTestCase
import com.intellij.python.junit5Tests.framework.env.PythonBinaryPath
import com.intellij.python.junit5Tests.randomBinary
@@ -15,7 +15,7 @@ import org.junit.jupiter.api.Test
class PythonWithLanguageLevelImplTest {
@Test
fun testRainyDay(): Unit = runBlocking {
when (val r = PythonWithLanguageLevelImpl.createByPythonBinary(randomBinary)) {
when (val r = VanillaPythonWithLanguageLevelImpl.createByPythonBinary(randomBinary)) {
is Result.Failure -> Unit
is Result.Success -> fail("Unexpected success ${r.result}")
}
@@ -23,7 +23,7 @@ class PythonWithLanguageLevelImplTest {
@Test
fun testSunnyDay(@PythonBinaryPath pythonBinary: PythonBinary): Unit = runBlocking {
val python = PythonWithLanguageLevelImpl.createByPythonBinary(pythonBinary).orThrow()
val python = VanillaPythonWithLanguageLevelImpl.createByPythonBinary(pythonBinary).orThrow()
assertEquals(pythonBinary, python.pythonBinary, "Wrong python binary")
assertTrue(python.languageLevel.isPy3K, "Wrong python version")
}

View File

@@ -1,7 +1,7 @@
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.python.junit5Tests.unit
import com.intellij.python.community.services.internal.impl.PythonWithLanguageLevelImpl
import com.intellij.python.community.services.internal.impl.VanillaPythonWithLanguageLevelImpl
import com.intellij.testFramework.junit5.TestApplication
import com.jetbrains.python.psi.LanguageLevel
import org.junit.jupiter.api.Assertions.assertArrayEquals
@@ -14,9 +14,9 @@ class CompareByLanguageLevelTest {
@Test
fun testCompareByLanguageLevel(@TempDir path: Path) {
val list = listOf(
PythonWithLanguageLevelImpl(path, LanguageLevel.PYTHON38),
PythonWithLanguageLevelImpl(path, LanguageLevel.PYTHON312),
PythonWithLanguageLevelImpl(path, LanguageLevel.PYTHON311),
VanillaPythonWithLanguageLevelImpl(path, LanguageLevel.PYTHON38),
VanillaPythonWithLanguageLevelImpl(path, LanguageLevel.PYTHON312),
VanillaPythonWithLanguageLevelImpl(path, LanguageLevel.PYTHON311),
)
val sortedLevels = list.sorted().map { it.languageLevel }.toTypedArray()

View File

@@ -1,7 +1,7 @@
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.python.junit5Tests.unit.alsoWin.services.internal.impl
import com.intellij.python.community.services.internal.impl.PythonWithLanguageLevelImpl
import com.intellij.python.community.services.internal.impl.VanillaPythonWithLanguageLevelImpl
import com.intellij.testFramework.junit5.TestApplication
import com.jetbrains.python.psi.LanguageLevel
import kotlinx.coroutines.runBlocking
@@ -23,7 +23,7 @@ class ReadableNameTest {
@Test
fun testNoHomePath(@TempDir path: Path): Unit = runBlocking {
val fakePython = path.resolve(PYTHON_FILE_NAME)
val name = PythonWithLanguageLevelImpl(fakePython, LanguageLevel.PYTHON312).getReadableName()
val name = VanillaPythonWithLanguageLevelImpl(fakePython, LanguageLevel.PYTHON312).getReadableName()
assertThat("Wrong name generated", name, allOf(containsString("3.12"), containsString(fakePython.pathString)))
}
@@ -33,11 +33,11 @@ class ReadableNameTest {
var fakePython = home.resolve(PYTHON_FILE_NAME)
var name = PythonWithLanguageLevelImpl(fakePython, LanguageLevel.PYTHON312).getReadableName()
var name = VanillaPythonWithLanguageLevelImpl(fakePython, LanguageLevel.PYTHON312).getReadableName()
assertThat("Wrong name generated", name, allOf(containsString("3.12"), matchesPattern(".*~[\\\\/]$PYTHON_FILE_NAME.*")))
fakePython = home.resolve("deep").resolve(PYTHON_FILE_NAME)
name = PythonWithLanguageLevelImpl(fakePython, LanguageLevel.PYTHON312).getReadableName()
name = VanillaPythonWithLanguageLevelImpl(fakePython, LanguageLevel.PYTHON312).getReadableName()
assertThat("Wrong name generated", name, allOf(containsString("3.12"), matchesPattern(".*~[\\\\/]deep[\\\\/]$PYTHON_FILE_NAME.*")))
}
}

View File

@@ -17,6 +17,7 @@ jvm_library(
"//python/openapi:community",
"@lib//:jetbrains-annotations",
"//platform/eel-provider",
"//python/python-exec-service/execService.python",
],
runtime_deps = [":shared_resources"]
)

View File

@@ -16,5 +16,6 @@
<orderEntry type="library" scope="TEST" name="kotlinx-coroutines-core" level="project" />
<orderEntry type="module" module-name="intellij.platform.testFramework.junit5" scope="TEST" />
<orderEntry type="library" scope="TEST" name="hamcrest" level="project" />
<orderEntry type="module" module-name="intellij.python.community.execService.python" />
</component>
</module>

View File

@@ -1,16 +1,24 @@
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.python.community.services.shared
import com.jetbrains.python.PythonBinary
import com.intellij.python.community.execService.python.advancedApi.ExecutablePython
import com.jetbrains.python.psi.LanguageLevel
import org.jetbrains.annotations.Nls
/**
* Python (vanilla, conda, whatever) with known language level.
*/
interface PythonWithLanguageLevel : Comparable<PythonWithLanguageLevel> {
val pythonBinary: PythonBinary
val languageLevel: LanguageLevel
/**
* Convert python to something that can be executed on [java.util.concurrent.ExecutorService]
*/
val asExecutablePython: ExecutablePython
/**
* Name can be displayed to the end user
*/
suspend fun getReadableName(): @Nls String
}

View File

@@ -0,0 +1,15 @@
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.python.community.services.shared
import com.intellij.python.community.execService.python.advancedApi.ExecutablePython
import com.jetbrains.python.PythonBinary
/**
* Vanilla (not conda) has [pythonBinary]
*/
interface VanillaPythonWithLanguageLevel : PythonWithLanguageLevel {
val pythonBinary: PythonBinary
override val asExecutablePython: ExecutablePython get() = ExecutablePython.Companion.VanillaExecutablePython(pythonBinary)
}

View File

@@ -32,6 +32,7 @@ jvm_library(
"//python/services/internal-impl:python-community-services-internal-impl",
"//platform/util",
"//python/installer",
"//python/python-venv:community-impl-venv",
],
exports = ["//python/services/shared"],
runtime_deps = [":system-python_resources"]

View File

@@ -28,7 +28,7 @@
<orderEntry type="module" module-name="intellij.platform.util" />
<orderEntry type="module" module-name="intellij.python.community.junit5Tests.framework" scope="TEST" />
<orderEntry type="module" module-name="intellij.python.community.impl.installer" />
<orderEntry type="module" module-name="intellij.python.community.impl.venv" scope="TEST" />
<orderEntry type="module" module-name="intellij.python.community.impl.venv" />
<orderEntry type="module" module-name="intellij.python.community.testFramework.testEnv" scope="TEST" />
<orderEntry type="library" scope="TEST" name="io.mockk" level="project" />
<orderEntry type="library" scope="TEST" name="io.mockk.jvm" level="project" />

View File

@@ -3,5 +3,7 @@
<module name="intellij.python.community"/>
<module name="intellij.python.psi.impl"/>
<module name="intellij.python.sdk"/>
<module name="intellij.python.community.execService"/>
<module name="intellij.python.community.impl.venv"/>
</dependencies>
</idea-plugin>

View File

@@ -5,11 +5,16 @@ import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.components.service
import com.intellij.platform.eel.EelApi
import com.intellij.platform.eel.provider.localEel
import com.intellij.python.community.services.shared.PythonWithLanguageLevel
import com.intellij.python.community.impl.venv.createVenv
import com.intellij.python.community.services.shared.VanillaPythonWithLanguageLevel
import com.jetbrains.python.PythonBinary
import com.jetbrains.python.Result
import com.jetbrains.python.errorProcessing.PyResult
import com.jetbrains.python.venvReader.Directory
import com.jetbrains.python.venvReader.VirtualEnvReader
import org.jetbrains.annotations.ApiStatus
import org.jetbrains.annotations.ApiStatus.Internal
import org.jetbrains.annotations.CheckReturnValue
import org.jetbrains.annotations.Nls
import javax.swing.Icon
@@ -50,7 +55,7 @@ fun SystemPythonService(): SystemPythonService = ApplicationManager.getApplicati
*
* Instances could be obtained with [SystemPythonService]
*/
class SystemPython internal constructor(private val impl: PythonWithLanguageLevel, val ui: UICustomization?) : PythonWithLanguageLevel by impl {
class SystemPython internal constructor(private val impl: VanillaPythonWithLanguageLevel, val ui: UICustomization?) : VanillaPythonWithLanguageLevel by impl {
override fun equals(other: Any?): Boolean {
if (this === other) return true
@@ -95,4 +100,16 @@ data class UICustomization(
*/
val title: @Nls String,
val icon: Icon? = null,
)
)
/**
* See [createVenv]
*/
@Internal
@CheckReturnValue
suspend fun createVenvFromSystemPython(
python: SystemPython,
venvDir: Directory,
inheritSitePackages: Boolean = false,
envReader: VirtualEnvReader = VirtualEnvReader.Instance,
): PyResult<PythonBinary> = createVenv(python.pythonBinary, venvDir, inheritSitePackages, envReader)

View File

@@ -11,7 +11,7 @@ import com.intellij.platform.eel.EelDescriptor
import com.intellij.platform.eel.provider.getEelDescriptor
import com.intellij.platform.eel.provider.localEel
import com.intellij.python.community.impl.installer.PySdkToInstallManager
import com.intellij.python.community.services.internal.impl.PythonWithLanguageLevelImpl
import com.intellij.python.community.services.internal.impl.VanillaPythonWithLanguageLevelImpl
import com.intellij.python.community.services.systemPython.SystemPythonServiceImpl.MyServiceState
import com.intellij.python.community.services.systemPython.impl.Cache
import com.intellij.python.community.services.systemPython.impl.CoreSystemPythonProvider
@@ -61,7 +61,7 @@ internal class SystemPythonServiceImpl(scope: CoroutineScope) : SystemPythonServ
}
override suspend fun registerSystemPython(pythonPath: PythonBinary): PyResult<SystemPython> {
val pythonWithLangLevel = PythonWithLanguageLevelImpl.createByPythonBinary(pythonPath).getOr { return it }
val pythonWithLangLevel = VanillaPythonWithLanguageLevelImpl.createByPythonBinary(pythonPath).getOr { return it }
val systemPython = SystemPython(pythonWithLangLevel, null)
state.userProvidedPythons.add(pythonPath.pathString)
cache()?.get(pythonPath.getEelDescriptor())?.add(systemPython)
@@ -119,7 +119,7 @@ internal class SystemPythonServiceImpl(scope: CoroutineScope) : SystemPythonServ
val badPythons = mutableSetOf<PythonBinary>()
val pythons = pythonsFromExtensions + state.userProvidedPythonsAsPath.filter { it.getEelDescriptor() == eelApi.descriptor }
val result = PythonWithLanguageLevelImpl.createByPythonBinaries(pythons.toSet())
val result = VanillaPythonWithLanguageLevelImpl.createByPythonBinaries(pythons.toSet())
.mapNotNull { (python, r) ->
when (r) {
is Result.Success -> SystemPython(r.result, pythonsUi[r.result.pythonBinary])

View File

@@ -15,7 +15,9 @@ import com.intellij.openapi.vfs.VirtualFile
import com.intellij.platform.util.progress.withProgressText
import com.intellij.python.community.execService.python.validatePythonAndGetVersion
import com.intellij.python.community.impl.venv.createVenv
import com.intellij.python.community.services.systemPython.SystemPython
import com.intellij.python.community.services.systemPython.SystemPythonService
import com.intellij.python.community.services.systemPython.createVenvFromSystemPython
import com.jetbrains.python.*
import com.jetbrains.python.errorProcessing.MessageError
import com.jetbrains.python.errorProcessing.PyResult
@@ -66,7 +68,7 @@ suspend fun createVenvAndSdk(
val systemPythonBinary = getSystemPython(confirmInstallation = confirmInstallation, systemPythonService).getOr { return it }
logger.info("no venv in $venvDirPath, using system python $systemPythonBinary to create venv")
// create venv using this system python
venvPython = createVenv(systemPythonBinary, venvDir = venvDirPath).getOr {
venvPython = createVenvFromSystemPython(systemPythonBinary, venvDir = venvDirPath).getOr {
return it
}
}
@@ -115,7 +117,7 @@ private suspend fun findExistingVenv(
private suspend fun getSystemPython(
confirmInstallation: suspend () -> Boolean,
pythonService: SystemPythonService,
): Result<PythonBinary, MessageError> {
): Result<SystemPython, MessageError> {
// First, find the latest python according to strategy
@@ -146,7 +148,7 @@ private suspend fun getSystemPython(
return PyResult.localizedError(PyBundle.message("project.error.all.pythons.bad"))
}
else {
Result.Success(systemPythonBinary.pythonBinary)
Result.Success(systemPythonBinary)
}
}

View File

@@ -6,7 +6,7 @@ import com.intellij.openapi.module.Module
import com.intellij.openapi.observable.properties.ObservableMutableProperty
import com.intellij.openapi.observable.util.notEqualsTo
import com.intellij.openapi.ui.validation.DialogValidationRequestor
import com.intellij.python.community.services.shared.PythonWithLanguageLevel
import com.intellij.python.community.services.shared.VanillaPythonWithLanguageLevel
import com.intellij.ui.dsl.builder.Panel
import com.jetbrains.python.PyBundle.message
import com.jetbrains.python.newProject.collector.InterpreterStatisticsInfo
@@ -81,7 +81,7 @@ internal abstract class CustomExistingEnvironmentSelector(
)
}
private fun addEnvByPath(python: PythonWithLanguageLevel) {
private fun addEnvByPath(python: VanillaPythonWithLanguageLevel) {
val interpreter = ManuallyAddedSelectableInterpreter(python)
existingEnvironments.value += interpreter
}

View File

@@ -14,8 +14,8 @@ import com.intellij.openapi.observable.properties.PropertyGraph
import com.intellij.openapi.projectRoots.Sdk
import com.intellij.openapi.util.io.NioFiles
import com.intellij.openapi.vfs.toNioPathOrNull
import com.intellij.python.community.services.internal.impl.PythonWithLanguageLevelImpl
import com.intellij.python.community.services.shared.PythonWithLanguageLevel
import com.intellij.python.community.services.internal.impl.VanillaPythonWithLanguageLevelImpl
import com.intellij.python.community.services.shared.VanillaPythonWithLanguageLevel
import com.intellij.python.community.services.systemPython.SystemPython
import com.intellij.python.community.services.systemPython.SystemPythonService
import com.intellij.python.community.services.systemPython.UICustomization
@@ -209,7 +209,7 @@ abstract class PythonAddInterpreterModel(
val existingSdkPaths = existingSelectableInterpreters.mapNotNull { tryResolvePath(it.homePath) }.toSet()
// Venvs are not detected manually, but must migrate to VenvService or so
val venvs: List<PythonWithLanguageLevel> = PythonWithLanguageLevelImpl.createByPythonBinaries(
val venvs: List<VanillaPythonWithLanguageLevel> = VanillaPythonWithLanguageLevelImpl.createByPythonBinaries(
VirtualEnvSdkFlavor.getInstance().suggestLocalHomePaths(null, null)).mapNotNull { (venv, r) ->
when (r) {
is Result.Failure -> {
@@ -241,7 +241,7 @@ abstract class PythonAddInterpreterModel(
state.selectedInterpreter.set(interpreter)
}
internal fun addInterpreter(python: PythonWithLanguageLevel): PythonSelectableInterpreter {
internal fun addInterpreter(python: VanillaPythonWithLanguageLevel): PythonSelectableInterpreter {
val interpreter = ManuallyAddedSelectableInterpreter(python).also { addManuallyAddedInterpreter(it) }
return interpreter
}
@@ -424,7 +424,7 @@ class ManuallyAddedSelectableInterpreter(
override val homePath: String,
override val languageLevel: LanguageLevel,
) : PythonSelectableInterpreter() {
constructor(python: PythonWithLanguageLevel) : this(python.pythonBinary.pathString, python.languageLevel)
constructor(python: VanillaPythonWithLanguageLevel) : this(python.pythonBinary.pathString, python.languageLevel)
override fun toString(): String {
return "ManuallyAddedSelectableInterpreter(homePath='$homePath', languageLevel=$languageLevel)"

View File

@@ -10,7 +10,8 @@ import com.intellij.openapi.vfs.VfsUtil
import com.intellij.platform.ide.progress.ModalTaskOwner
import com.intellij.platform.ide.progress.TaskCancellation
import com.intellij.platform.ide.progress.withModalProgress
import com.intellij.python.community.impl.venv.createVenv
import com.intellij.python.community.services.systemPython.SystemPythonService
import com.intellij.python.community.services.systemPython.createVenvFromSystemPython
import com.jetbrains.python.PyBundle.message
import com.jetbrains.python.errorProcessing.PyResult
import com.jetbrains.python.sdk.*
@@ -33,8 +34,10 @@ suspend fun PythonMutableTargetAddInterpreterModel.setupVirtualenv(venvPath: Pat
is DetectedSelectableInterpreter, is ManuallyAddedSelectableInterpreter -> baseSdk.homePath
}!!)
val systemPython = SystemPythonService().registerSystemPython(baseSdkPath).getOr { return it }
val venvPython = createVenv(baseSdkPath, venvPath, inheritSitePackages = state.inheritSitePackages.get()).getOr { return it }
val venvPython = createVenvFromSystemPython(systemPython, venvPath, inheritSitePackages = state.inheritSitePackages.get()).getOr { return it }
if (targetEnvironmentConfiguration != null) {
error("Remote targets aren't supported")

View File

@@ -22,7 +22,7 @@ import com.intellij.openapi.util.NlsSafe
import com.intellij.platform.ide.progress.ModalTaskOwner
import com.intellij.platform.ide.progress.runWithModalProgressBlocking
import com.intellij.python.community.impl.installer.CondaInstallManager
import com.intellij.python.community.services.shared.PythonWithLanguageLevel
import com.intellij.python.community.services.shared.VanillaPythonWithLanguageLevel
import com.intellij.ui.AnimatedIcon
import com.intellij.ui.ColoredListCellRenderer
import com.intellij.ui.SimpleColoredComponent
@@ -252,7 +252,7 @@ internal fun Panel.pythonInterpreterComboBox(
selectedSdkProperty: ObservableMutableProperty<PythonSelectableInterpreter?>, // todo not sdk
model: PythonAddInterpreterModel,
validationRequestor: DialogValidationRequestor,
onPathSelected: (PythonWithLanguageLevel) -> Unit,
onPathSelected: (VanillaPythonWithLanguageLevel) -> Unit,
customizer: RowsRange.() -> Unit = {},
): PythonInterpreterComboBox {
val comboBox = PythonInterpreterComboBox(model, onPathSelected, ShowingMessageErrorSync)
@@ -292,7 +292,7 @@ internal fun Panel.pythonInterpreterComboBox(
internal class PythonInterpreterComboBox(
val controller: PythonAddInterpreterModel,
val onPathSelected: (PythonWithLanguageLevel) -> Unit,
val onPathSelected: (VanillaPythonWithLanguageLevel) -> Unit,
private val errorSink: ErrorSink,
) : ComboBox<PythonSelectableInterpreter?>() {