mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-04-17 12:01:25 +07:00
[python]: PY-85585 : Do not display vens as system pythons in "Add new interpreter" window.
Instead of old `addManuallyAddedInterpreter` we now have two functions: one that requires system python and one that doesn't. Both functions register system python if provided, but the latter one accepts any python (venv included). Various "selectors" use these functions. We also make sure no non-system python is set to `baseInterpreters`: base are always system! As a bonus, we show "system" or "virtual env" title near interpreter. It now checks that python is system (see `ensureSystemPython`). Non-system pythons are never reported, and `registerSystemPython` also returns an error for non-system pythons We need `execGetBoolFromStdout` for the further changes Merge-request: IJ-MR-182415 Merged-by: Ilya Kazakevich <ilya.kazakevich@jetbrains.com> (cherry picked from commit 2950f5f0cd2745c12987a92e40774d366568f312) GitOrigin-RevId: f30e9a6cd7b5d103454d66f26a0c2282d7c587fc
This commit is contained in:
committed by
intellij-monorepo-bot
parent
ed0fda649a
commit
3388536d2c
@@ -1,10 +1,13 @@
|
||||
// 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.execService.python
|
||||
|
||||
import com.intellij.openapi.util.NlsSafe
|
||||
import com.intellij.python.community.execService.*
|
||||
import com.intellij.python.community.execService.python.advancedApi.ExecutablePython
|
||||
import com.intellij.python.community.execService.python.advancedApi.executeHelperAdvanced
|
||||
import com.intellij.python.community.execService.python.advancedApi.validatePythonAndGetInfo
|
||||
import com.intellij.python.community.execService.python.impl.execGetStdoutBoolImpl
|
||||
import com.intellij.python.community.execService.python.impl.execGetStdoutImpl
|
||||
import com.intellij.python.community.helpersLocator.PythonHelpersLocator
|
||||
import com.jetbrains.python.PythonBinary
|
||||
import com.jetbrains.python.PythonInfo
|
||||
@@ -42,6 +45,24 @@ suspend fun PythonBinaryOnEelOrTarget.validatePythonAndGetInfo(): PyResult<Pytho
|
||||
suspend fun ExecService.validatePythonAndGetInfo(python: PythonBinary): PyResult<PythonInfo> = validatePythonAndGetInfo(python.asBinToExec())
|
||||
suspend fun PythonBinary.validatePythonAndGetInfo(): PyResult<PythonInfo> = asBinToExec().validatePythonAndGetInfo()
|
||||
|
||||
/**
|
||||
* Execute [pythonCode] on [ExecutablePython] and (if exitcode is 0) return stdout
|
||||
*/
|
||||
suspend fun ExecutablePython.execGetStdout(pythonCode: @NlsSafe String, execService: ExecService = ExecService()): PyResult<String> = execService.execGetStdoutImpl(this, pythonCode, ZeroCodeStdoutTransformer)
|
||||
suspend fun PythonBinaryOnEelOrTarget.execGetStdout(pythonCode: @NlsSafe String, execService: ExecService = ExecService()): PyResult<String> = execService.execGetStdoutImpl(ExecutablePython.vanillaExecutablePython(this), pythonCode, ZeroCodeStdoutTransformer)
|
||||
|
||||
/**
|
||||
* Execute [pythonCode] on [ExecutablePython] and (if exitcode is 0) return stdout converted to [Boolean]. Useful for things like:
|
||||
* ```kotlin
|
||||
* when (val r = executeGetBoolFromStdout("print(some_system_check()")) {
|
||||
* is Success<*> -> {/*r is true of false*/}
|
||||
* is Failure<*> -> {/*r is an error here*/}
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
suspend fun ExecutablePython.execGetBoolFromStdout(pythonCode: @NlsSafe String, execService: ExecService = ExecService()): PyResult<Boolean> = execService.execGetStdoutBoolImpl(this, pythonCode)
|
||||
suspend fun PythonBinaryOnEelOrTarget.execGetBoolFromStdout(pythonCode: @NlsSafe String, execService: ExecService = ExecService()): PyResult<Boolean> = execService.execGetStdoutBoolImpl(ExecutablePython.vanillaExecutablePython(this), pythonCode)
|
||||
|
||||
|
||||
/**
|
||||
* Adds helper by copying it to the remote system (if needed)
|
||||
|
||||
@@ -29,18 +29,7 @@ private const val GIL_CHECK_CMD = "from __future__ import print_function; import
|
||||
@ApiStatus.Internal
|
||||
internal suspend fun ExecService.validatePythonAndGetInfoImpl(python: ExecutablePython): PyResult<PythonInfo> = withContext(Dispatchers.IO) {
|
||||
val options = ExecOptions(timeout = 1.minutes)
|
||||
val gilCheckOutput = executePythonAdvanced(
|
||||
python,
|
||||
Args("-c", GIL_CHECK_CMD),
|
||||
processInteractiveHandler = transformerToHandler(null, ZeroCodeStdoutTransformer),
|
||||
options = options
|
||||
).getOr(message("python.cannot.exec", python.userReadableName)) { return@withContext it }.trim()
|
||||
|
||||
val freeThreaded = when (gilCheckOutput) {
|
||||
"True" -> false
|
||||
"False" -> true
|
||||
else -> return@withContext PyResult.localizedError(message("python.get.version.error", python.userReadableName, gilCheckOutput))
|
||||
}
|
||||
val freeThreaded = !execGetStdoutBoolImpl(python, GIL_CHECK_CMD).getOr(message("python.check.threading.fail")) { return@withContext it }
|
||||
|
||||
val versionOutput: EelProcessExecutionResult = executePythonAdvanced(python, options = options, args = Args(PYTHON_VERSION_ARG), processInteractiveHandler = transformerToHandler<EelProcessExecutionResult>(null) { r ->
|
||||
if (r.exitCode == 0) Result.success(r) else Result.failure(message("python.get.version.error", python.userReadableName, r.exitCode))
|
||||
@@ -55,6 +44,21 @@ internal suspend fun ExecService.validatePythonAndGetInfoImpl(python: Executable
|
||||
return@withContext Result.success(PythonInfo(languageLevel, freeThreaded))
|
||||
}
|
||||
|
||||
@ApiStatus.Internal
|
||||
internal suspend fun ExecService.execGetStdoutBoolImpl(python: ExecutablePython, command: @NlsSafe String): PyResult<Boolean> = execGetStdoutImpl(python, command, ZeroCodeStdoutTransformerBool)
|
||||
|
||||
@ApiStatus.Internal
|
||||
internal suspend fun <T : Any> ExecService.execGetStdoutImpl(python: ExecutablePython, command: @NlsSafe String, transformer: ZeroCodeStdoutTransformerTyped<T>): PyResult<T> = withContext(Dispatchers.IO) {
|
||||
val options = ExecOptions(timeout = 1.minutes)
|
||||
val result = executePythonAdvanced(
|
||||
python,
|
||||
Args("-c", command),
|
||||
processInteractiveHandler = transformerToHandler(null, transformer),
|
||||
options = options
|
||||
).getOr(message("python.cannot.exec", python.userReadableName)) { return@withContext it }
|
||||
return@withContext Result.success(result)
|
||||
}
|
||||
|
||||
private val ExecutablePython.userReadableName: @NlsSafe String
|
||||
get() =
|
||||
(listOf(when (binary) {
|
||||
|
||||
Reference in New Issue
Block a user