mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-04-18 20:41:22 +07:00
Python: extract python-specific extensions from exec service to simplify API and make it extendable for intepreters.
Use `ExecService` `api.kt` to exec any binary and extensions from `execService.python/api.kt` for python-specific things (i.e helpers) GitOrigin-RevId: bb217798a9d1ee886c4b12220ec1f66a5ef08336
This commit is contained in:
committed by
intellij-monorepo-bot
parent
fd2ad62299
commit
2e14347844
@@ -83,7 +83,3 @@ path.validation.ends.with.whitespace=Path ends with a whitespace
|
||||
path.validation.file.not.found=File {0} is not found
|
||||
path.validation.invalid=Path is invalid: {0}
|
||||
path.validation.inaccessible=Path is inaccessible
|
||||
|
||||
python.get.version.error={0} returned error: {1}
|
||||
python.get.version.too.long={0} took too long
|
||||
python.get.version.wrong.version={0} has a wrong version: {1}
|
||||
|
||||
@@ -1,68 +1,13 @@
|
||||
package com.jetbrains.python
|
||||
|
||||
import com.intellij.openapi.util.NlsSafe
|
||||
import com.intellij.platform.eel.EelPlatform
|
||||
import com.intellij.platform.eel.ExecuteProcessException
|
||||
import com.intellij.platform.eel.provider.getEelDescriptor
|
||||
import com.intellij.platform.eel.provider.utils.EelProcessExecutionResult
|
||||
import com.intellij.platform.eel.provider.utils.exec
|
||||
import com.intellij.platform.eel.provider.utils.stderrString
|
||||
import com.intellij.platform.eel.provider.utils.stdoutString
|
||||
import com.intellij.util.concurrency.annotations.RequiresBackgroundThread
|
||||
import com.jetbrains.python.PySdkBundle.message
|
||||
import com.jetbrains.python.errorProcessing.PyResult
|
||||
import com.jetbrains.python.psi.LanguageLevel
|
||||
import com.jetbrains.python.sdk.flavors.PythonSdkFlavor.PYTHON_VERSION_ARG
|
||||
import com.jetbrains.python.sdk.flavors.PythonSdkFlavor.getLanguageLevelFromVersionStringStaticSafe
|
||||
import com.jetbrains.python.venvReader.VirtualEnvReader
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.withContext
|
||||
import org.jetbrains.annotations.ApiStatus
|
||||
import kotlin.io.path.name
|
||||
import kotlin.io.path.pathString
|
||||
import kotlin.time.Duration.Companion.seconds
|
||||
|
||||
|
||||
/**
|
||||
* Ensures that this python is executable and returns its version. 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
|
||||
*/
|
||||
@ApiStatus.Internal
|
||||
suspend fun PythonBinary.validatePythonAndGetVersion(): PyResult<LanguageLevel> = withContext(Dispatchers.IO) {
|
||||
val smokeTestOutput = executeWithResult("-c", "print(1)").getOr { return@withContext it }.stdoutString.trim()
|
||||
if (smokeTestOutput != "1") {
|
||||
return@withContext PyResult.localizedError(message("python.get.version.error", pathString, smokeTestOutput))
|
||||
}
|
||||
|
||||
val versionOutput = executeWithResult(PYTHON_VERSION_ARG).getOr { return@withContext it }
|
||||
// Python 2 might return version as stderr, see https://bugs.python.org/issue18338
|
||||
val versionString = versionOutput.stdoutString.let { it.ifBlank { versionOutput.stderrString } }
|
||||
val languageLevel = getLanguageLevelFromVersionStringStaticSafe(versionString.trim())
|
||||
if (languageLevel == null) {
|
||||
return@withContext PyResult.localizedError(message("python.get.version.wrong.version", pathString, versionOutput))
|
||||
}
|
||||
return@withContext Result.success(languageLevel)
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes [this] with [args], returns either output or error (if execution failed or exit code != 0)
|
||||
*/
|
||||
private suspend fun PythonBinary.executeWithResult(vararg args: String): PyResult<@NlsSafe EelProcessExecutionResult> {
|
||||
try {
|
||||
val output = exec(*args, timeout = 5.seconds)
|
||||
return if (output.exitCode != 0) {
|
||||
PyResult.localizedError(message("python.get.version.error", pathString, "code ${output.exitCode}, ${output.stderrString}"))
|
||||
}
|
||||
else {
|
||||
Result.success(output)
|
||||
}
|
||||
} catch (e : ExecuteProcessException) {
|
||||
return PyResult.localizedError(e.localizedMessage)
|
||||
}
|
||||
}
|
||||
|
||||
@RequiresBackgroundThread
|
||||
@ApiStatus.Internal
|
||||
fun PythonBinary.resolvePythonHome(): PythonHomePath = when (getEelDescriptor().platform) {
|
||||
|
||||
@@ -34,6 +34,7 @@ import java.util.concurrent.TimeUnit;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static com.jetbrains.python.PythonBinaryKt.PYTHON_VERSION_ARG;
|
||||
import static com.jetbrains.python.sdk.flavors.PySdkFlavorUtilKt.getFileExecutionError;
|
||||
import static com.jetbrains.python.sdk.flavors.PySdkFlavorUtilKt.getFileExecutionErrorOnEdt;
|
||||
import static com.jetbrains.python.venvReader.ResolveUtilKt.tryResolvePath;
|
||||
@@ -65,12 +66,6 @@ public abstract class PythonSdkFlavor<D extends PyFlavorData> {
|
||||
|
||||
private static final Pattern VERSION_RE = Pattern.compile("(Python \\S+).*");
|
||||
private static final Logger LOG = Logger.getInstance(PythonSdkFlavor.class);
|
||||
/**
|
||||
* <code>
|
||||
* python --version
|
||||
* </code>
|
||||
*/
|
||||
public static final String PYTHON_VERSION_ARG = "--version";
|
||||
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user