Files
openide/python/python-exec-service/execService.python/src/api.kt
Ilya.Kazakevich 3e9fa8d2dd [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)

(cherry picked from commit f30e9a6cd7b5d103454d66f26a0c2282d7c587fc)

GitOrigin-RevId: 6894d00debe969ecdfdadd1a7ba0d44866d9bf53
2025-11-26 16:42:51 +00:00

71 lines
3.8 KiB
Kotlin

// 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
import com.jetbrains.python.errorProcessing.PyResult
/**
* Python binary itself (i.e python.exe)
*/
typealias PythonBinaryOnEelOrTarget = BinaryToExec
/**
* Execute [helper] on [python]. For remote eels, [helper] is copied (but only one file!).
* Returns `stdout`
*/
suspend fun ExecService.executeHelper(
python: BinaryToExec,
helper: HelperName,
args: List<String> = emptyList(),
options: ExecOptions = ExecOptions(),
procListener: PyProcessListener? = null,
): PyResult<String> =
executeHelperAdvanced(ExecutablePython.vanillaExecutablePython(python), helper, args, options, procListener, ZeroCodeStdoutTransformer)
/**
* Ensures that this python is executable and returns its info. Error if python is broken.
*
* Some pythons might be broken: they may be executable, even return a version, but still fail to execute it.
* As we need workable pythons, we validate it by executing
*/
suspend fun ExecService.validatePythonAndGetInfo(python: PythonBinaryOnEelOrTarget): PyResult<PythonInfo> =
validatePythonAndGetInfo(ExecutablePython.vanillaExecutablePython(python))
suspend fun PythonBinaryOnEelOrTarget.validatePythonAndGetInfo(): PyResult<PythonInfo> = ExecService().validatePythonAndGetInfo(this)
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)
*/
fun Args.addHelper(helper: HelperName): Args =
addLocalFile(PythonHelpersLocator.findPathInHelpers(helper))