Python: VirtualEnvReader refactoring: move the same module as PythonSdkUtil, and substitute a couple of methods.

`PythonSdkUtil` duplicates VER logic. One Jython-specific thing was also removed as we do not need Jython anymore

GitOrigin-RevId: 658fc42b485ac074a6d89fce3c7408e51cdc8f95
This commit is contained in:
Ilya.Kazakevich
2024-08-12 21:08:02 +02:00
committed by intellij-monorepo-bot
parent d8b8f63677
commit b1a4c55771
22 changed files with 89 additions and 121 deletions

View File

@@ -93,14 +93,14 @@ class PyPipfileSdkConfiguration : PyProjectSdkConfigurationExtension {
return null
}
val path = PythonSdkUtil.getPythonExecutable(pipEnv).also {
val path = VirtualEnvReader.Instance.findPythonInPythonRoot(Path.of(pipEnv)).also {
if (it == null) {
PySdkConfigurationCollector.logPipEnv(module.project, PipEnvResult.NO_EXECUTABLE)
LOGGER.warn("Python executable is not found: $pipEnv")
}
} ?: return null
val file = LocalFileSystem.getInstance().refreshAndFindFileByPath(path).also {
val file = LocalFileSystem.getInstance().refreshAndFindFileByPath(path.toString()).also {
if (it == null) {
PySdkConfigurationCollector.logPipEnv(module.project, PipEnvResult.NO_EXECUTABLE_FILE)
LOGGER.warn("Python executable file is not found: $path")

View File

@@ -91,13 +91,13 @@ class PyPoetrySdkConfiguration : PyProjectSdkConfigurationExtension {
return null
}
val path = PythonSdkUtil.getPythonExecutable(poetry).also {
val path = VirtualEnvReader.Instance.findPythonInPythonRoot(Path.of(poetry)).also {
if (it == null) {
LOGGER.warn("Python executable is not found: $poetry")
}
} ?: return null
val file = LocalFileSystem.getInstance().refreshAndFindFileByPath(path).also {
val file = LocalFileSystem.getInstance().refreshAndFindFileByPath(path.toString()).also {
if (it == null) {
LOGGER.warn("Python executable file is not found: $path")
}

View File

@@ -15,12 +15,15 @@ import com.intellij.openapi.util.NlsSafe;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.openapi.util.io.FileSystemUtil;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.*;
import com.intellij.openapi.vfs.StandardFileSystems;
import com.intellij.openapi.vfs.VfsUtil;
import com.intellij.openapi.vfs.VfsUtilCore;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.util.ObjectUtils;
import com.intellij.util.SystemProperties;
import com.intellij.util.concurrency.annotations.RequiresBackgroundThread;
import com.intellij.util.containers.ContainerUtil;
import com.jetbrains.python.PyNames;
import com.jetbrains.python.PythonRuntimeService;
@@ -66,9 +69,6 @@ public final class PythonSdkUtil {
*/
public static final OrderRootType BUILTIN_ROOT_TYPE = OrderRootType.CLASSES;
static final String[] WINDOWS_EXECUTABLE_SUFFIXES = {"cmd", "exe", "bat", "com"};
private static final String[] DIRS_WITH_BINARY = {"", "bin", "Scripts", "net45"};
private static final String[] UNIX_BINARY_NAMES = {"jython", "pypy", "python", "python3"};
private static final String[] WIN_BINARY_NAMES = {"jython.bat", "ipy.exe", "pypy.exe", "python.exe", "python3.exe"};
private static final Predicate<Sdk> REMOTE_SDK_PREDICATE = PythonSdkUtil::isRemote;
private static final Key<PySkeletonHeader> CACHED_SKELETON_HEADER = Key.create("CACHED_SKELETON_HEADER");
@@ -316,66 +316,27 @@ public final class PythonSdkUtil {
return getAllSdks().stream().filter(REMOTE_SDK_PREDICATE.negate()).collect(Collectors.toList());
}
// It is only here for external plugins
@Nullable
@RequiresBackgroundThread(generateAssertion = false)
public static String getPythonExecutable(@NotNull String rootPath) {
final File rootFile = new File(rootPath);
if (rootFile.isFile()) {
return rootFile.getAbsolutePath();
}
for (String dir : DIRS_WITH_BINARY) {
final File subDir;
if (StringUtil.isEmpty(dir)) {
subDir = rootFile;
}
else {
subDir = new File(rootFile, dir);
}
if (!subDir.isDirectory()) {
continue;
}
for (String binaryName : getBinaryNames()) {
final File executable = new File(subDir, binaryName);
if (executable.isFile()) {
return executable.getAbsolutePath();
}
}
}
return null;
var python = VirtualEnvReader.getInstance().findPythonInPythonRoot(Path.of(rootPath));
return (python != null) ? python.toString() : null;
}
/**
* @deprecated use {@link #getExecutablePath(Path, String)}
*/
@Deprecated
@Nullable
@RequiresBackgroundThread(generateAssertion = false)
public static String getExecutablePath(@NotNull final String homeDirectory, @NotNull String name) {
File binPath = new File(homeDirectory);
File binDir = binPath.getParentFile();
if (binDir == null) return null;
VirtualFileSystem localVfs = StandardFileSystems.local();
File runner = new File(binDir, name);
if (runner.exists()) return localVfs.extractPresentableUrl(runner.getPath());
runner = new File(new File(binDir, "Scripts"), name);
if (runner.exists()) return localVfs.extractPresentableUrl(runner.getPath());
runner = new File(new File(binDir.getParentFile(), "Scripts"), name);
if (runner.exists()) return localVfs.extractPresentableUrl(runner.getPath());
runner = new File(new File(binDir.getParentFile(), "local"), name);
if (runner.exists()) return localVfs.extractPresentableUrl(runner.getPath());
runner = new File(new File(new File(binDir.getParentFile(), "local"), "bin"), name);
if (runner.exists()) return localVfs.extractPresentableUrl(runner.getPath());
// if interpreter is a symlink
if (FileSystemUtil.isSymLink(homeDirectory)) {
String resolvedPath = FileSystemUtil.resolveSymLink(homeDirectory);
if (resolvedPath != null) {
return getExecutablePath(resolvedPath, name);
}
}
// Search in standard unix path
runner = new File(new File("/usr", "bin"), name);
if (runner.exists()) return localVfs.extractPresentableUrl(runner.getPath());
runner = new File(new File(new File("/usr", "local"), "bin"), name);
if (runner.exists()) return localVfs.extractPresentableUrl(runner.getPath());
return null;
Path path = getExecutablePath(Path.of(homeDirectory), name);
return (path != null) ? path.toString() : null;
}
@Nullable
@RequiresBackgroundThread(generateAssertion = false)
public static Path getExecutablePath(@NotNull Path homeDirectory, @NotNull String name) {
Path binDir = homeDirectory.getParent();
if (binDir == null) return null;
@@ -459,14 +420,6 @@ public final class PythonSdkUtil {
return null;
}
private static String[] getBinaryNames() {
if (SystemInfo.isUnix) {
return UNIX_BINARY_NAMES;
}
else {
return WIN_BINARY_NAMES;
}
}
@Nullable
public static Sdk findSdkByKey(@NotNull String key) {

View File

@@ -1,12 +1,10 @@
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.jetbrains.python.sdk.flavors
package com.jetbrains.python.sdk
import com.intellij.openapi.util.IntellijInternalApi
import com.intellij.openapi.util.SystemInfoRt
import com.intellij.openapi.util.io.toCanonicalPath
import com.intellij.util.SystemProperties
import com.intellij.util.concurrency.annotations.RequiresBackgroundThread
import com.jetbrains.python.sdk.tryResolvePath
import org.jetbrains.annotations.ApiStatus
import org.jetbrains.annotations.NonNls
import java.io.IOException
@@ -19,7 +17,6 @@ import kotlin.io.path.*
typealias PythonBinary = Path
typealias Directory = Path
@IntellijInternalApi
@ApiStatus.Internal
class VirtualEnvReader(
private val envs: Map<@NonNls String, @NonNls String> = System.getenv(),
@@ -105,7 +102,7 @@ class VirtualEnvReader(
* [dir] is root directory of python installation or virtualenv
*/
@RequiresBackgroundThread
private fun findPythonInPythonRoot(dir: Directory): PythonBinary? {
fun findPythonInPythonRoot(dir: Directory): PythonBinary? {
if (!dir.isDirectory()) {
return null
}

View File

@@ -33,6 +33,7 @@ import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.awt.*;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
@@ -67,8 +68,8 @@ public class SphinxBaseCommand {
setTitle(RestBundle.message("sphinx.set.working.directory.dialog.title"));
init();
VirtualFile baseDir = project.getBaseDir();
String path = baseDir != null? baseDir.getPath() : "";
VirtualFile baseDir = project.getBaseDir();
String path = baseDir != null ? baseDir.getPath() : "";
myInputFile.setText(path);
myInputFile.setEditable(false);
myInputFile.addBrowseFolderListener(RestBundle.message("sphinx.choose.working.directory.browse.folder.title"), null, project,
@@ -134,7 +135,8 @@ public class SphinxBaseCommand {
GeneralCommandLine cmd = new GeneralCommandLine();
if (sdkHomePath != null) {
final String runnerName = "sphinx-quickstart" + (SystemInfo.isWindows ? ".exe" : "");
String executablePath = PythonSdkUtil.getExecutablePath(sdkHomePath, runnerName);
var executablePathNio = PythonSdkUtil.getExecutablePath(Path.of(sdkHomePath), runnerName);
String executablePath = executablePathNio != null ? executablePathNio.toString() : null;
if (executablePath != null) {
cmd.setExePath(executablePath);
}
@@ -143,7 +145,7 @@ public class SphinxBaseCommand {
}
}
cmd.setWorkDirectory(service.getWorkdir().isEmpty()? module.getProject().getBasePath(): service.getWorkdir());
cmd.setWorkDirectory(service.getWorkdir().isEmpty() ? module.getProject().getBasePath() : service.getWorkdir());
PythonCommandLineState.createStandardGroups(cmd);
ParamsGroup scriptParams = cmd.getParametersList().getParamsGroup(PythonCommandLineState.GROUP_SCRIPT);
assert scriptParams != null;
@@ -172,5 +174,4 @@ public class SphinxBaseCommand {
return cmd;
}
}

View File

@@ -9,11 +9,13 @@ import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.jetbrains.python.PySdkBundle;
import com.jetbrains.python.sdk.PythonSdkUtil;
import com.jetbrains.python.sdk.VirtualEnvReader;
import com.jetbrains.python.sdk.flavors.PyCondaRunKt;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.File;
import java.nio.file.Path;
import java.util.*;
public class PyCondaPackageManagerImpl extends PyPackageManagerImpl {
@@ -148,9 +150,9 @@ public class PyCondaPackageManagerImpl extends PyPackageManagerImpl {
final ArrayList<String> parameters = Lists.newArrayList("create", "-p", destinationDir, "-y", "python=" + version);
PyCondaRunKt.runConda(condaExecutable, parameters);
final String binary = PythonSdkUtil.getPythonExecutable(destinationDir);
final Path binary = VirtualEnvReader.getInstance().findPythonInPythonRoot(Path.of(destinationDir));
final String binaryFallback = destinationDir + File.separator + "bin" + File.separator + "python";
return (binary != null) ? binary : binaryFallback;
return (binary != null) ? binary.toString() : binaryFallback;
}
@Override

View File

@@ -26,6 +26,7 @@ import org.jetbrains.annotations.Nullable;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.*;
@@ -193,10 +194,10 @@ public class PyPackageManagerImpl extends PyPackageManagerImplBase {
showSdkExecutionException(sdk, e, PySdkBundle.message("python.creating.venv.failed.title"));
}
final String binary = PythonSdkUtil.getPythonExecutable(destinationDir);
final Path binary = VirtualEnvReader.getInstance().findPythonInPythonRoot(Paths.get(destinationDir));
final String binaryFallback = destinationDir + mySeparator + "bin" + mySeparator + "python";
return (binary != null) ? binary : binaryFallback;
return (binary != null) ? binary.toString() : binaryFallback;
}
/**

View File

@@ -37,11 +37,13 @@ import com.jetbrains.python.run.target.HelpersAwareTargetEnvironmentRequest;
import com.jetbrains.python.sdk.PyLazySdk;
import com.jetbrains.python.sdk.PySdkExtKt;
import com.jetbrains.python.sdk.PythonSdkUtil;
import com.jetbrains.python.sdk.VirtualEnvReader;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.*;
@@ -237,11 +239,11 @@ public class PyTargetEnvironmentPackageManager extends PyPackageManagerImplBase
// TODO [targets] Pass `parentDir = null`
getPythonProcessResult(pythonExecution, false, true, targetEnvironmentRequest);
final String binary = PythonSdkUtil.getPythonExecutable(destinationDir);
final Path binary = VirtualEnvReader.getInstance().findPythonInPythonRoot(Path.of(destinationDir));
final char separator = targetEnvironmentRequest.getTargetPlatform().getPlatform().fileSeparator;
final String binaryFallback = destinationDir + separator + "bin" + separator + "python";
return (binary != null) ? binary : binaryFallback;
return (binary != null) ? binary.toString() : binaryFallback;
}
/**

View File

@@ -5,7 +5,6 @@ import com.intellij.execution.target.TargetEnvironmentConfiguration
import com.intellij.execution.target.joinTargetPaths
import com.intellij.openapi.fileChooser.FileChooserDescriptorFactory
import com.intellij.openapi.module.Module
import com.intellij.openapi.observable.properties.PropertyGraph
import com.intellij.openapi.project.Project
import com.intellij.openapi.projectRoots.Sdk
import com.intellij.openapi.projectRoots.impl.SdkConfigurationUtil
@@ -33,7 +32,7 @@ import com.jetbrains.python.sdk.configuration.createSdkForTarget
import com.jetbrains.python.sdk.configuration.createVirtualEnvSynchronously
import com.jetbrains.python.sdk.flavors.PyFlavorAndData
import com.jetbrains.python.sdk.flavors.PyFlavorData
import com.jetbrains.python.sdk.flavors.VirtualEnvReader.Companion.DEFAULT_VIRTUALENVS_DIR
import com.jetbrains.python.sdk.VirtualEnvReader.Companion.DEFAULT_VIRTUALENVS_DIR
import com.jetbrains.python.target.PyTargetAwareAdditionalData
import com.jetbrains.python.target.PythonLanguageRuntimeConfiguration
import java.awt.BorderLayout

View File

@@ -5,7 +5,7 @@ import com.intellij.openapi.application.EDT
import com.intellij.openapi.projectRoots.Sdk
import com.intellij.openapi.util.io.toNioPathOrNull
import com.jetbrains.python.sdk.ModuleOrProject
import com.jetbrains.python.sdk.flavors.VirtualEnvReader
import com.jetbrains.python.sdk.VirtualEnvReader
import com.jetbrains.python.sdk.rootManager
import com.jetbrains.python.sdk.service.PySdkService.Companion.pySdkService
import kotlinx.coroutines.Dispatchers

View File

@@ -14,6 +14,7 @@ import com.intellij.platform.ide.progress.runWithModalProgressBlocking
import com.jetbrains.python.PyBundle
import com.jetbrains.python.sdk.PythonSdkType
import com.jetbrains.python.sdk.PythonSdkUtil
import com.jetbrains.python.sdk.VirtualEnvReader
import com.jetbrains.python.sdk.add.target.conda.createCondaSdkFromExistingEnv
import com.jetbrains.python.sdk.excludeInnerVirtualEnv
import com.jetbrains.python.sdk.flavors.conda.PyCondaCommand
@@ -41,7 +42,7 @@ internal fun PythonMutableTargetAddInterpreterModel.setupVirtualenv(venvPath: Pa
inheritSitePackages = state.inheritSitePackages.get())
if (targetEnvironmentConfiguration != null) error("Remote targets aren't supported")
val venvPython = PythonSdkUtil.getPythonExecutable(venvPathOnTarget)
val venvPython = VirtualEnvReader.Instance.findPythonInPythonRoot(Path.of(venvPathOnTarget))?.toString()
val homeFile = try {
StandardFileSystems.local().refreshAndFindFileByPath(venvPython!!)!!

View File

@@ -5,6 +5,7 @@ import com.google.common.collect.Sets;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.openapi.util.UserDataHolder;
import com.jetbrains.python.sdk.VirtualEnvReader;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

View File

@@ -11,6 +11,7 @@ import com.jetbrains.python.icons.PythonIcons;
import com.jetbrains.python.sdk.BasePySdkExtKt;
import com.jetbrains.python.sdk.PySdkExtKt;
import com.jetbrains.python.sdk.PythonSdkUtil;
import com.jetbrains.python.sdk.VirtualEnvReader;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

View File

@@ -122,7 +122,7 @@ fun setupPipEnvSdkUnderProgress(project: Project?,
override fun compute(indicator: ProgressIndicator): String {
indicator.isIndeterminate = true
val pipEnv = setupPipEnv(FileUtil.toSystemDependentName(projectPath), python, installPackages)
return PythonSdkUtil.getPythonExecutable(pipEnv) ?: FileUtil.join(pipEnv, "bin", "python")
return VirtualEnvReader.Instance.findPythonInPythonRoot(Path.of(pipEnv))?.toString() ?: FileUtil.join(pipEnv, "bin", "python")
}
}
return createSdkByGenerateTask(task, existingSdks, null, projectPath, suggestedSdkName(projectPath))?.apply {

View File

@@ -210,4 +210,4 @@ inline fun <reified T> syncRunPoetry(
}
}
fun getPythonExecutable(homePath: String): String = PythonSdkUtil.getPythonExecutable(homePath) ?: FileUtil.join(homePath, "bin", "python")
fun getPythonExecutable(homePath: String): String = VirtualEnvReader.Instance.findPythonInPythonRoot(Path.of(homePath))?.toString() ?: FileUtil.join(homePath, "bin", "python")

View File

@@ -20,7 +20,7 @@ import com.jetbrains.python.sdk.PythonSdkAdditionalData
import com.jetbrains.python.sdk.PythonSdkType
import com.jetbrains.python.sdk.PythonSdkUtil
import com.jetbrains.python.sdk.flavors.PythonSdkFlavor
import com.jetbrains.python.sdk.flavors.VirtualEnvReader
import com.jetbrains.python.sdk.VirtualEnvReader
import com.jetbrains.python.sdk.flavors.conda.CondaEnvSdkFlavor
import com.jetbrains.python.sdk.pipenv.isPipEnv
import com.jetbrains.python.sdk.poetry.isPoetry

View File

@@ -17,10 +17,12 @@ import com.jetbrains.python.PyNames
import com.jetbrains.python.packaging.PyPackagingSettings
import com.jetbrains.python.sdk.PythonSdkUpdater
import com.jetbrains.python.sdk.PythonSdkUtil
import com.jetbrains.python.sdk.VirtualEnvReader
import com.jetbrains.python.tools.sdkTools.PySdkTools
import com.jetbrains.python.tools.sdkTools.SdkCreationType
import java.io.File
import java.nio.file.Paths
import kotlin.io.path.Path
internal val TestPath = System.getenv("PYCHARM_PERF_ENVS")
@@ -30,7 +32,7 @@ fun createSdkForPerformance(module: Module,
sdkHome: String = File(TestPath, "envs/py36_64").absolutePath): Sdk {
ApplicationManagerEx.setInStressTest(true)
// To disable slow debugging
val executable = File(PythonSdkUtil.getPythonExecutable(sdkHome) ?: throw AssertionError("No python on $sdkHome"))
val executable = VirtualEnvReader.Instance.findPythonInPythonRoot(Path(sdkHome))?.toFile() ?: throw AssertionError("No python on $sdkHome")
println("Creating Python SDK $sdkHome")
return PySdkTools.createTempSdk(VfsUtil.findFileByIoFile(executable, true)!!, sdkCreationType, module,
PyPackagingSettings.getInstance(module.project))

View File

@@ -14,6 +14,7 @@ import com.jetbrains.LoggingRule;
import com.jetbrains.python.psi.LanguageLevel;
import com.jetbrains.python.sdk.PySdkUtil;
import com.jetbrains.python.sdk.PythonSdkUtil;
import com.jetbrains.python.sdk.VirtualEnvReader;
import com.jetbrains.python.sdk.flavors.PythonSdkFlavor;
import com.jetbrains.python.tools.sdkTools.PySdkTools;
import com.jetbrains.python.tools.sdkTools.SdkCreationType;
@@ -21,6 +22,7 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.File;
import java.nio.file.Path;
import java.util.*;
public class PyEnvTaskRunner {
@@ -74,10 +76,10 @@ public class PyEnvTaskRunner {
else {
testTask.useNormalTimeout();
}
final String executable = PythonSdkUtil.getPythonExecutable(root);
final Path executable = VirtualEnvReader.getInstance().findPythonInPythonRoot(Path.of(root));
assert executable != null : "No executable in " + root;
final Sdk sdk = getSdk(executable, testTask);
final Sdk sdk = getSdk(executable.toString(), testTask);
if (skipOnFlavors != null) {
final PythonSdkFlavor flavor = PythonSdkFlavor.getFlavor(sdk);
if (ContainerUtil.exists(skipOnFlavors, o -> o.isInstance(flavor))) {
@@ -101,7 +103,7 @@ public class PyEnvTaskRunner {
}
testTask.runTestOn(executable, sdk);
testTask.runTestOn(executable.toString(), sdk);
passedRoots.add(root);
}

View File

@@ -9,6 +9,7 @@ import com.jetbrains.env.PyEnvTestCase
import com.jetbrains.env.PyEnvTestSettings
import com.jetbrains.python.packaging.findCondaExecutableRelativeToEnv
import com.jetbrains.python.sdk.PythonSdkUtil
import com.jetbrains.python.sdk.VirtualEnvReader
import com.jetbrains.python.sdk.add.target.conda.TargetEnvironmentRequestCommandExecutor
import com.jetbrains.python.sdk.flavors.conda.PyCondaEnv
import com.jetbrains.python.sdk.flavors.conda.PyCondaEnvIdentity
@@ -37,9 +38,9 @@ sealed class PythonType<T : Any>(private val tag: @NonNls String) {
.map { it.toPath() }
.firstOrNull { typeMatchesEnv(it, *additionalTags) }
?.let { envDir ->
Result.success(pythonPathToEnvironment(Path.of(
PythonSdkUtil.getPythonExecutable(envDir.toString())
?: error("Can't find python binary in $envDir")), envDir)) // This is a misconfiguration, hence an error
Result.success(pythonPathToEnvironment(
VirtualEnvReader.Instance.findPythonInPythonRoot(envDir)
?: error("Can't find python binary in $envDir"), envDir)) // This is a misconfiguration, hence an error
}
?: Result.failure(Throwable("No python found. See ${PyEnvTestSettings::class} class for more info"))

View File

@@ -1,9 +1,10 @@
package com.jetbrains.python.sdk.flavors
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.jetbrains.python.sdk
import com.intellij.grazie.grammar.assertIsEmpty
import com.intellij.openapi.util.io.FileUtilRt
import com.intellij.testFramework.utils.io.deleteRecursively
import org.junit.Assert.*
import org.junit.Assert
import org.junit.Test
import java.nio.file.Files
import java.nio.file.Path
@@ -95,24 +96,24 @@ class VirtualEnvReaderTest {
// just version
bootstrap.setupPyenv(listOf("3.1.1"), "python")
var interpreters = bootstrap.virtualEnvReader.findPyenvInterpreters()
assertEquals(1, interpreters.size)
Assert.assertEquals(1, interpreters.size)
assert(interpreters[0].absolutePathString().startsWith(bootstrap.pyenv.absolutePathString()))
assert(interpreters[0].absolutePathString().endsWith("python"))
// another version w/o match
bootstrap.setupPyenv(listOf("3.2.1"), "xxx")
interpreters = bootstrap.virtualEnvReader.findPyenvInterpreters()
assertEquals(1, interpreters.size)
Assert.assertEquals(1, interpreters.size)
// both in names
bootstrap.setupPyenv(listOf("3.2.2"), "pypy")
interpreters = bootstrap.virtualEnvReader.findPyenvInterpreters()
assertEquals(2, interpreters.size)
Assert.assertEquals(2, interpreters.size)
assert(interpreters[0] != interpreters[1])
bootstrap.removeVersion(bootstrap.pyenv, "3.2.2")
interpreters = bootstrap.virtualEnvReader.findPyenvInterpreters()
assertEquals(1, interpreters.size)
Assert.assertEquals(1, interpreters.size)
assert(interpreters[0].absolutePathString().endsWith("python"))
}
@@ -120,24 +121,24 @@ class VirtualEnvReaderTest {
fun testIsPyenvSdk() {
val bootstrap = Bootstrap()
assertFalse(bootstrap.virtualEnvReader.isPyenvSdk(null as String?))
assertFalse(bootstrap.virtualEnvReader.isPyenvSdk(""))
assertFalse(bootstrap.virtualEnvReader.isPyenvSdk("aa\u0000bb"))
assertFalse(bootstrap.virtualEnvReader.isPyenvSdk("a/b/c/d"))
assertFalse(bootstrap.virtualEnvReader.isPyenvSdk(bootstrap.cwd))
assertFalse(bootstrap.virtualEnvReader.isPyenvSdk(bootstrap.cwd.resolve("smthg")))
Assert.assertFalse(bootstrap.virtualEnvReader.isPyenvSdk(null as String?))
Assert.assertFalse(bootstrap.virtualEnvReader.isPyenvSdk(""))
Assert.assertFalse(bootstrap.virtualEnvReader.isPyenvSdk("aa\u0000bb"))
Assert.assertFalse(bootstrap.virtualEnvReader.isPyenvSdk("a/b/c/d"))
Assert.assertFalse(bootstrap.virtualEnvReader.isPyenvSdk(bootstrap.cwd))
Assert.assertFalse(bootstrap.virtualEnvReader.isPyenvSdk(bootstrap.cwd.resolve("smthg")))
bootstrap.setupPyenv(listOf("3.2.1"), "xxxx")
assertFalse(bootstrap.virtualEnvReader.isPyenvSdk(null as String?))
assertFalse(bootstrap.virtualEnvReader.isPyenvSdk(""))
assertFalse(bootstrap.virtualEnvReader.isPyenvSdk("aa\u0000bb"))
assertFalse(bootstrap.virtualEnvReader.isPyenvSdk("a/b/c/d"))
assertFalse(bootstrap.virtualEnvReader.isPyenvSdk(bootstrap.cwd))
assertFalse(bootstrap.virtualEnvReader.isPyenvSdk(bootstrap.cwd.resolve("smthg")))
Assert.assertFalse(bootstrap.virtualEnvReader.isPyenvSdk(null as String?))
Assert.assertFalse(bootstrap.virtualEnvReader.isPyenvSdk(""))
Assert.assertFalse(bootstrap.virtualEnvReader.isPyenvSdk("aa\u0000bb"))
Assert.assertFalse(bootstrap.virtualEnvReader.isPyenvSdk("a/b/c/d"))
Assert.assertFalse(bootstrap.virtualEnvReader.isPyenvSdk(bootstrap.cwd))
Assert.assertFalse(bootstrap.virtualEnvReader.isPyenvSdk(bootstrap.cwd.resolve("smthg")))
// particularly any path inside pyenv root will work
assertTrue(bootstrap.virtualEnvReader.isPyenvSdk(bootstrap.pyenv.resolve("xxx")))
Assert.assertTrue(bootstrap.virtualEnvReader.isPyenvSdk(bootstrap.pyenv.resolve("xxx")))
// should resolve symlinks
val link = bootstrap.cwd.resolve("smthg")
@@ -145,9 +146,9 @@ class VirtualEnvReaderTest {
// hanging links, should not resolve it
Files.createSymbolicLink(link, target)
assertFalse(bootstrap.virtualEnvReader.isPyenvSdk(link))
Assert.assertFalse(bootstrap.virtualEnvReader.isPyenvSdk(link))
Files.createFile(target)
assertTrue(bootstrap.virtualEnvReader.isPyenvSdk(link))
Assert.assertTrue(bootstrap.virtualEnvReader.isPyenvSdk(link))
}
}

View File

@@ -5,11 +5,13 @@ import com.intellij.openapi.vfs.VfsUtil
import com.intellij.testFramework.TestApplicationManager
import com.intellij.util.io.Compressor
import com.jetbrains.python.sdk.PythonSdkUtil
import com.jetbrains.python.sdk.VirtualEnvReader
import com.jetbrains.python.sdk.skeletons.DefaultPregeneratedSkeletonsProvider
import com.jetbrains.python.sdk.skeletons.PySkeletonRefresher
import com.jetbrains.python.tools.sdkTools.PySdkTools
import com.jetbrains.python.tools.sdkTools.SdkCreationType
import java.io.File
import kotlin.io.path.Path
import kotlin.math.abs
import kotlin.system.exitProcess
@@ -29,7 +31,7 @@ fun main() {
for (python in File(root).listFiles()!!) {
println("Running on $python")
val executable = PythonSdkUtil.getPythonExecutable(python.absolutePath)!!
val executable = VirtualEnvReader.Instance.findPythonInPythonRoot(Path(python.absolutePath))!!.toString()
val sdk = PySdkTools.createTempSdk(VfsUtil.findFileByIoFile(File(executable), true)!!, SdkCreationType.SDK_PACKAGES_ONLY, null, null)
val skeletonsDir = File(workingDir, "skeletons-${sdk.versionString!!.replace(" ", "_")}_" + abs(sdk.homePath!!.hashCode()))

View File

@@ -3,9 +3,11 @@ package com.jetbrains.python.tools
import com.jetbrains.python.PythonHelper
import com.jetbrains.python.sdk.PythonSdkUtil
import com.jetbrains.python.sdk.VirtualEnvReader
import java.io.BufferedReader
import java.io.File
import java.io.InputStreamReader
import kotlin.io.path.Path
fun main() {
@@ -21,7 +23,7 @@ fun main() {
}
val sdkHome = python.absolutePath
val executable = PythonSdkUtil.getPythonExecutable(sdkHome)?.let { File(it) }
val executable = VirtualEnvReader.Instance.findPythonInPythonRoot(Path(sdkHome))?.toFile()
if (executable == null) {
println("No python on $sdkHome")