mirror of
https://gitflic.ru/project/openide/openide.git
synced 2025-12-16 22:51:17 +07:00
Python: hide symbols
GitOrigin-RevId: 2653974b9d8ba190fb9a1aea8c36759e8ddc42d3
This commit is contained in:
committed by
intellij-monorepo-bot
parent
531e3b1667
commit
c16d6840e8
@@ -1,10 +1,8 @@
|
||||
package com.jetbrains.python
|
||||
|
||||
import com.intellij.openapi.util.NlsSafe
|
||||
import com.intellij.platform.eel.EelExecApi
|
||||
import com.intellij.platform.eel.EelPlatform
|
||||
import com.intellij.platform.eel.ExecuteProcessException
|
||||
import com.intellij.platform.eel.getOr
|
||||
import com.intellij.platform.eel.provider.getEelDescriptor
|
||||
import com.intellij.platform.eel.provider.utils.EelProcessExecutionResult
|
||||
import com.intellij.platform.eel.provider.utils.exec
|
||||
@@ -66,12 +64,14 @@ private suspend fun PythonBinary.executeWithResult(vararg args: String): Result<
|
||||
}
|
||||
|
||||
@RequiresBackgroundThread
|
||||
@ApiStatus.Internal
|
||||
fun PythonBinary.resolvePythonHome(): PythonHomePath = when (getEelDescriptor().platform) {
|
||||
is EelPlatform.Windows -> parent.takeIf { it.name.lowercase() != "scripts" } ?: parent.parent
|
||||
is EelPlatform.Posix -> parent.takeIf { it.name != "bin" } ?: parent.parent
|
||||
}
|
||||
|
||||
@RequiresBackgroundThread
|
||||
@ApiStatus.Internal
|
||||
fun PythonHomePath.resolvePythonBinary(): PythonBinary? {
|
||||
return VirtualEnvReader(isWindows = getEelDescriptor().platform is EelPlatform.Windows).findPythonInPythonRoot(this)
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ import com.intellij.openapi.util.SystemInfo
|
||||
import com.intellij.openapi.vfs.LocalFileSystem
|
||||
import com.intellij.util.SystemProperties
|
||||
import com.jetbrains.python.sdk.PythonSdkUtil
|
||||
import org.jetbrains.annotations.ApiStatus
|
||||
import java.nio.file.Files
|
||||
import java.nio.file.Path
|
||||
import kotlin.io.path.div
|
||||
@@ -28,6 +29,8 @@ private const val UNIX_OPT_PATH = "/opt/"
|
||||
|
||||
private val LOG = Logger.getInstance("#com.jetbrains.python.packaging")
|
||||
|
||||
@ApiStatus.Internal
|
||||
|
||||
fun getCondaBasePython(systemCondaExecutable: String): String? {
|
||||
val condaFile = LocalFileSystem.getInstance().findFileByPath(systemCondaExecutable)
|
||||
if (condaFile != null) {
|
||||
@@ -42,6 +45,8 @@ fun getCondaBasePython(systemCondaExecutable: String): String? {
|
||||
|
||||
private fun getPythonName(): String = if (SystemInfo.isWindows) PYTHON_EXE_NAME else PYTHON_UNIX_BINARY_NAME
|
||||
|
||||
@ApiStatus.Internal
|
||||
|
||||
fun findCondaExecutableRelativeToEnv(pyExecutable: Path): Path? {
|
||||
if (!Files.exists(pyExecutable)) {
|
||||
return null
|
||||
@@ -112,8 +117,7 @@ private fun findExecutable(condaName: String, condaFolder: Path): Path? {
|
||||
if (!Files.exists(bin)) return null
|
||||
return PythonSdkUtil.getExecutablePath(bin, condaName)
|
||||
}
|
||||
|
||||
fun getSystemCondaExecutable(): Path? {
|
||||
internal fun getSystemCondaExecutable(): Path? {
|
||||
val condaName = if (SystemInfo.isWindows) CONDA_BAT_NAME else CONDA_BINARY_NAME
|
||||
|
||||
// TODO we need another findInPath() that works with Path-s
|
||||
|
||||
@@ -9,7 +9,7 @@ import com.intellij.openapi.util.NlsSafe;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class IndicatedProcessOutputListener extends ProcessAdapter {
|
||||
public final class IndicatedProcessOutputListener extends ProcessAdapter {
|
||||
private final @NotNull ProgressIndicator myIndicator;
|
||||
|
||||
public IndicatedProcessOutputListener(@NotNull ProgressIndicator indicator) {
|
||||
|
||||
@@ -17,8 +17,11 @@ package com.jetbrains.python.sdk;
|
||||
|
||||
|
||||
import com.intellij.openapi.util.NlsContexts.DialogMessage;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
|
||||
public class InvalidSdkException extends Exception {
|
||||
@ApiStatus.Internal
|
||||
|
||||
public final class InvalidSdkException extends Exception {
|
||||
public InvalidSdkException(@DialogMessage String s) {
|
||||
super(s);
|
||||
}
|
||||
|
||||
@@ -13,6 +13,8 @@ import org.jetbrains.annotations.ApiStatus.Internal
|
||||
*
|
||||
* This method creates new in this case, but only if an SDK flavor doesn't require special additional data.
|
||||
*/
|
||||
@Internal
|
||||
|
||||
fun Sdk.getOrCreateAdditionalData(): PythonSdkAdditionalData {
|
||||
val existingData = sdkAdditionalData as? PythonSdkAdditionalData
|
||||
if (existingData != null) {
|
||||
|
||||
@@ -68,10 +68,14 @@ public final class PySdkUtil {
|
||||
* @param timeout how many milliseconds to wait until the process terminates; non-positive means inifinity.
|
||||
* @return a tuple of (stdout lines, stderr lines, exit_code), lines in them have line terminators stripped, or may be null.
|
||||
*/
|
||||
@ApiStatus.Internal
|
||||
|
||||
public static @NotNull ProcessOutput getProcessOutput(String homePath, @NonNls String[] command, final int timeout) {
|
||||
return getProcessOutput(homePath, command, null, timeout);
|
||||
}
|
||||
|
||||
@ApiStatus.Internal
|
||||
|
||||
public static @NotNull ProcessOutput getProcessOutput(String homePath,
|
||||
@NonNls String[] command,
|
||||
@Nullable @NonNls Map<String, String> extraEnv,
|
||||
@@ -79,6 +83,8 @@ public final class PySdkUtil {
|
||||
return getProcessOutput(homePath, command, extraEnv, timeout, null, true);
|
||||
}
|
||||
|
||||
@ApiStatus.Internal
|
||||
|
||||
public static @NotNull ProcessOutput getProcessOutput(String homePath,
|
||||
@NonNls String[] command,
|
||||
@Nullable @NonNls Map<String, String> extraEnv,
|
||||
@@ -88,6 +94,8 @@ public final class PySdkUtil {
|
||||
return getProcessOutput(new GeneralCommandLine(command), homePath, extraEnv, timeout, stdin, needEOFMarker);
|
||||
}
|
||||
|
||||
@ApiStatus.Internal
|
||||
|
||||
public static ProcessOutput getProcessOutput(@NotNull GeneralCommandLine cmd, @Nullable String homePath,
|
||||
@Nullable @NonNls Map<String, String> extraEnv,
|
||||
int timeout) {
|
||||
@@ -101,6 +109,8 @@ public final class PySdkUtil {
|
||||
return getProcessOutput(cmd, homePath, extraEnv, timeout, stdin, needEOFMarker, null);
|
||||
}
|
||||
|
||||
@ApiStatus.Internal
|
||||
|
||||
public static ProcessOutput getProcessOutput(@NotNull GeneralCommandLine cmd, @Nullable String homePath,
|
||||
@Nullable @NonNls Map<String, String> extraEnv,
|
||||
int timeout,
|
||||
@@ -244,6 +254,9 @@ public final class PySdkUtil {
|
||||
/**
|
||||
* @return name of builtins skeleton file; for Python 2.x it is '{@code __builtins__.py}'.
|
||||
*/
|
||||
|
||||
|
||||
@ApiStatus.Internal
|
||||
public static @NotNull @NonNls String getBuiltinsFileName(@NotNull Sdk sdk) {
|
||||
return PyBuiltinCache.getBuiltinsFileName(getLanguageLevelForSdk(sdk));
|
||||
}
|
||||
@@ -253,6 +266,7 @@ public final class PySdkUtil {
|
||||
*
|
||||
* @param allowRemote - indicates whether remote interpreter is acceptable
|
||||
*/
|
||||
@ApiStatus.Internal
|
||||
public static @Nullable Sdk findSdkForDirectory(@NotNull Project project, @NotNull Path workingDirectory, boolean allowRemote) {
|
||||
VirtualFile workingDirectoryVirtualFile = LocalFileSystem.getInstance().findFileByNioFile(workingDirectory);
|
||||
if (workingDirectoryVirtualFile != null) {
|
||||
|
||||
@@ -133,6 +133,7 @@ public class PythonSdkAdditionalData implements SdkAdditionalData {
|
||||
}
|
||||
}
|
||||
|
||||
@ApiStatus.Internal
|
||||
public final String getAssociatedModulePath() {
|
||||
return myAssociatedModulePath;
|
||||
}
|
||||
@@ -171,10 +172,14 @@ public class PythonSdkAdditionalData implements SdkAdditionalData {
|
||||
return myFlavorAndData.getFlavor();
|
||||
}
|
||||
|
||||
@ApiStatus.Internal
|
||||
|
||||
public final @NotNull PyFlavorAndData<?, ?> getFlavorAndData() {
|
||||
return myFlavorAndData;
|
||||
}
|
||||
|
||||
@ApiStatus.Internal
|
||||
|
||||
public static @NotNull PythonSdkAdditionalData loadFromElement(@Nullable Element element) {
|
||||
final PythonSdkAdditionalData data = new PythonSdkAdditionalData();
|
||||
data.load(element);
|
||||
@@ -219,11 +224,14 @@ public class PythonSdkAdditionalData implements SdkAdditionalData {
|
||||
}
|
||||
}
|
||||
|
||||
@ApiStatus.Internal
|
||||
|
||||
public final Set<VirtualFile> getAddedPathFiles() {
|
||||
return getPathsAsVirtualFiles(myAddedPaths);
|
||||
}
|
||||
|
||||
@ApiStatus.Internal
|
||||
|
||||
public final Set<VirtualFile> getExcludedPathFiles() {
|
||||
return getPathsAsVirtualFiles(myExcludedPaths);
|
||||
}
|
||||
@@ -231,6 +239,8 @@ public class PythonSdkAdditionalData implements SdkAdditionalData {
|
||||
/**
|
||||
* @see com.jetbrains.python.sdk.PyTransferredSdkRootsKt#getPathsToTransfer(Sdk)
|
||||
*/
|
||||
|
||||
@ApiStatus.Internal
|
||||
public final @NotNull Set<VirtualFile> getPathsToTransfer() {
|
||||
return getPathsAsVirtualFiles(myPathsToTransfer);
|
||||
}
|
||||
|
||||
@@ -28,12 +28,13 @@ import java.net.URL
|
||||
import java.nio.charset.StandardCharsets
|
||||
|
||||
|
||||
val LOG: Logger = logger<Sdks>()
|
||||
private val LOG: Logger = logger<Sdks>()
|
||||
|
||||
|
||||
/**
|
||||
* Currently only CPython is supported
|
||||
*/
|
||||
@ApiStatus.Internal
|
||||
enum class Product(val title: String) {
|
||||
CPython("Python"),
|
||||
Miniconda("Miniconda"),
|
||||
@@ -43,6 +44,7 @@ enum class Product(val title: String) {
|
||||
/**
|
||||
* Resource Type enum with autodetection via file extensions.
|
||||
*/
|
||||
@ApiStatus.Internal
|
||||
enum class ResourceType(vararg val extensions: String) {
|
||||
MICROSOFT_WINDOWS_EXECUTABLE("exe"),
|
||||
MICROSOFT_SOFTWARE_INSTALLER("msi"),
|
||||
@@ -62,6 +64,8 @@ enum class ResourceType(vararg val extensions: String) {
|
||||
* Url-specified file resource. FileName and ResourceType values are calculated by the Url provided (might be declared explicitly).
|
||||
* Downloaded size / sha256 should be verified to prevent consistency leaks.
|
||||
*/
|
||||
|
||||
@ApiStatus.Internal
|
||||
data class Resource(
|
||||
val url: Url,
|
||||
val size: Long,
|
||||
@@ -75,6 +79,7 @@ data class Resource(
|
||||
* Custom prepared installation packages per OS and ArchType.
|
||||
* Could contain multiple resources (in case of MSI for example)
|
||||
*/
|
||||
@ApiStatus.Internal
|
||||
data class Binary(
|
||||
val os: OS,
|
||||
val cpuArch: CpuArch?,
|
||||
@@ -89,12 +94,13 @@ data class Binary(
|
||||
* Bundle with release version of vendor. Might contain sources or any binary packages.
|
||||
* Vendor + Version is a primary key.
|
||||
*/
|
||||
@ApiStatus.Internal
|
||||
data class Release(
|
||||
val version: String,
|
||||
val product: Product,
|
||||
val sources: List<Resource>?,
|
||||
val binaries: List<Binary>?,
|
||||
val title: String = "${product.title} ${version}"
|
||||
val title: String = "${product.title} ${version}",
|
||||
) : Comparable<Release> {
|
||||
override fun compareTo(other: Release) = compareValuesBy(this, other, { it.product }, { it.version })
|
||||
override fun toString(): String {
|
||||
@@ -107,12 +113,14 @@ data class Release(
|
||||
* Class represents /sdks.json structure with all available SDK release mappings.
|
||||
* It has only python section currently.
|
||||
*/
|
||||
@ApiStatus.Internal
|
||||
data class Sdks(
|
||||
val python: List<Release> = listOf(),
|
||||
val conda: List<Release> = listOf(),
|
||||
)
|
||||
|
||||
|
||||
@ApiStatus.Internal
|
||||
fun Version?.toLanguageLevel(): LanguageLevel? = this?.let { LanguageLevel.fromPythonVersion("$major.$minor") }
|
||||
|
||||
|
||||
@@ -121,12 +129,14 @@ fun Version?.toLanguageLevel(): LanguageLevel? = this?.let { LanguageLevel.fromP
|
||||
*
|
||||
* @see com.intellij.util.Url
|
||||
*/
|
||||
@ApiStatus.Internal
|
||||
class UrlDeserializer : JsonDeserializer<Url>() {
|
||||
override fun deserialize(p: JsonParser?, ctxt: DeserializationContext?): Url {
|
||||
return Urls.parseEncoded(p!!.valueAsString)!!
|
||||
}
|
||||
}
|
||||
|
||||
@ApiStatus.Internal
|
||||
class UrlSerializer : JsonSerializer<Url>() {
|
||||
override fun serialize(value: Url?, gen: JsonGenerator?, serializers: SerializerProvider?) {
|
||||
value?.let {
|
||||
@@ -135,6 +145,8 @@ class UrlSerializer : JsonSerializer<Url>() {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ApiStatus.Internal
|
||||
object SdksKeeper {
|
||||
private val configUrl: URL? = Sdks::class.java.getResource("/sdks.json")
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@ import com.sun.jna.platform.win32.Kernel32.*
|
||||
import com.sun.jna.platform.win32.Ntifs
|
||||
import com.sun.jna.platform.win32.WinioctlUtil
|
||||
import com.sun.jna.ptr.IntByReference
|
||||
import org.jetbrains.annotations.ApiStatus
|
||||
import java.nio.ByteBuffer
|
||||
import java.nio.file.Path
|
||||
import kotlin.io.path.*
|
||||
@@ -41,6 +42,8 @@ private const val storeMarker = "DesktopAppInstaller"
|
||||
* There may be several files linked to this product, we need only first.
|
||||
* And for 3.7 there could be ``PythonSoftwareFoundation.Python.3.7_(SOME_OTHER_UID)``.
|
||||
*/
|
||||
|
||||
@ApiStatus.Internal
|
||||
fun getAppxFiles(expectedProduct: String?, filePattern: Regex): Collection<Path> =
|
||||
userAppxFolder?.listDirectoryEntries()
|
||||
?.filter { filePattern.matches(it.name) }
|
||||
|
||||
@@ -14,8 +14,14 @@ import com.intellij.openapi.progress.ProgressManager
|
||||
import com.intellij.openapi.projectRoots.Sdk
|
||||
import com.intellij.openapi.util.text.StringUtil
|
||||
import com.jetbrains.python.PySdkBundle
|
||||
import com.jetbrains.python.packaging.*
|
||||
import com.jetbrains.python.packaging.IndicatedProcessOutputListener
|
||||
import com.jetbrains.python.packaging.PyCondaPackageService
|
||||
import com.jetbrains.python.packaging.PyExecutionException
|
||||
import com.jetbrains.python.packaging.getCondaBasePython
|
||||
import com.jetbrains.python.sdk.PySdkUtil
|
||||
import org.jetbrains.annotations.ApiStatus
|
||||
|
||||
@ApiStatus.Internal
|
||||
|
||||
@Deprecated("Use Sdk.configureBuilderToRunPythonOnTarget")
|
||||
@Throws(ExecutionException::class)
|
||||
@@ -23,6 +29,8 @@ fun runConda(condaExecutable: String, arguments: List<String>): ProcessOutput {
|
||||
return run(condaExecutable, arguments, readCondaEnv(condaExecutable))
|
||||
}
|
||||
|
||||
@ApiStatus.Internal
|
||||
|
||||
@Deprecated("Use Sdk.configureBuilderToRunPythonOnTarget")
|
||||
@Throws(ExecutionException::class)
|
||||
fun runConda(sdk: Sdk?, arguments: List<String>): ProcessOutput {
|
||||
@@ -69,6 +77,8 @@ private fun ProcessOutput.checkExitCode(executable: String, arguments: List<Stri
|
||||
}
|
||||
}
|
||||
|
||||
@ApiStatus.Internal
|
||||
|
||||
@Deprecated("Use PyCondaEnv")
|
||||
@Throws(ExecutionException::class, JsonSyntaxException::class)
|
||||
fun listCondaEnvironments(condaExecutable: String): List<String> {
|
||||
|
||||
@@ -28,12 +28,16 @@ import kotlinx.coroutines.launch
|
||||
import org.jetbrains.annotations.ApiStatus
|
||||
import java.net.URI
|
||||
|
||||
@ApiStatus.Internal
|
||||
|
||||
sealed class PythonPackageInstallRequest(val title: String) {
|
||||
data object AllRequirements : PythonPackageInstallRequest("All Requirements")
|
||||
data class ByLocation(val location: URI) : PythonPackageInstallRequest(location.toString())
|
||||
data class ByRepositoryPythonPackageSpecification(val specification: PythonRepositoryPackageSpecification) : PythonPackageInstallRequest(specification.nameWithVersionSpec)
|
||||
}
|
||||
|
||||
@ApiStatus.Internal
|
||||
|
||||
fun PythonRepositoryPackageSpecification.toInstallRequest(): PythonPackageInstallRequest.ByRepositoryPythonPackageSpecification {
|
||||
return PythonPackageInstallRequest.ByRepositoryPythonPackageSpecification(this)
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
@file:JvmName("AddInterpreterActions")
|
||||
|
||||
package com.jetbrains.python.sdk
|
||||
@@ -25,8 +25,10 @@ import com.jetbrains.python.sdk.add.v2.PythonAddLocalInterpreterDialog
|
||||
import com.jetbrains.python.sdk.add.v2.PythonAddLocalInterpreterPresenter
|
||||
import com.jetbrains.python.target.PythonLanguageRuntimeType
|
||||
import com.jetbrains.python.util.ShowingMessageErrorSync
|
||||
import org.jetbrains.annotations.ApiStatus
|
||||
import java.util.function.Consumer
|
||||
|
||||
@ApiStatus.Internal
|
||||
fun collectAddInterpreterActions(moduleOrProject: ModuleOrProject, onSdkCreated: Consumer<Sdk>): List<AnAction> {
|
||||
// If module resides on this target, we can't use any target except same target and target types that explicitly allow that
|
||||
// example: on ``\\wsl$`` you can only use wsl target and dockers
|
||||
@@ -91,6 +93,8 @@ private class AddInterpreterOnTargetAction(
|
||||
}
|
||||
}
|
||||
|
||||
@ApiStatus.Internal
|
||||
|
||||
fun switchToSdk(module: Module, sdk: Sdk, currentSdk: Sdk?) {
|
||||
val project = module.project
|
||||
(sdk.sdkType as PythonSdkType).setupSdkPaths(sdk)
|
||||
|
||||
@@ -1,11 +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.jetbrains.python.sdk
|
||||
|
||||
import com.intellij.openapi.application.ApplicationManager
|
||||
import com.intellij.openapi.application.EDT
|
||||
import com.intellij.openapi.application.ModalityState
|
||||
import com.intellij.openapi.application.asContextElement
|
||||
import com.intellij.openapi.application.writeIntentReadAction
|
||||
import com.intellij.openapi.application.*
|
||||
import com.intellij.openapi.components.Service
|
||||
import com.intellij.openapi.components.service
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
@@ -13,6 +9,7 @@ import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.first
|
||||
import kotlinx.coroutines.launch
|
||||
import org.jetbrains.annotations.ApiStatus
|
||||
import java.util.function.Consumer
|
||||
|
||||
@Service
|
||||
@@ -21,6 +18,8 @@ private class MyService(val coroutineScope: CoroutineScope)
|
||||
/**
|
||||
* collects first item of flow in EDT and calls [consumer] to be used as an adapter.
|
||||
*/
|
||||
@ApiStatus.Internal
|
||||
|
||||
internal fun <T : Any> Flow<T>.oneShotConsumer(consumer: Consumer<T>) {
|
||||
ApplicationManager.getApplication().service<MyService>().coroutineScope.launch(Dispatchers.EDT + ModalityState.defaultModalityState().asContextElement()) {
|
||||
// Platform doesn't guarantee write intent lock on EDT
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// 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.jetbrains.python.sdk;
|
||||
|
||||
import com.intellij.openapi.projectRoots.Sdk;
|
||||
@@ -7,8 +7,11 @@ import com.intellij.remote.RemoteSdkAdditionalData;
|
||||
import com.intellij.remote.ext.LanguageCaseCollector;
|
||||
import com.intellij.util.ObjectUtils;
|
||||
import com.jetbrains.python.remote.PyCredentialsContribution;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@ApiStatus.Internal
|
||||
|
||||
public abstract class CredentialsTypeExChecker {
|
||||
public boolean check(final @Nullable Sdk sdk) {
|
||||
if (sdk == null) {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// 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.jetbrains.python.sdk;
|
||||
|
||||
import com.intellij.ide.macro.Macro;
|
||||
@@ -14,9 +14,11 @@ import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.util.PathUtil;
|
||||
import com.jetbrains.python.PyBundle;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@ApiStatus.Internal
|
||||
|
||||
public final class InterpreterDirectoryMacro extends Macro implements PathMacro {
|
||||
@Override
|
||||
|
||||
@@ -141,17 +141,25 @@ fun resetSystemWideSdksDetectors() {
|
||||
PythonSdkFlavor.getApplicableFlavors(false).forEach(PythonSdkFlavor<*>::dropCaches)
|
||||
}
|
||||
|
||||
@Internal
|
||||
|
||||
fun detectVirtualEnvs(module: Module?, existingSdks: List<Sdk>, context: UserDataHolder): List<PyDetectedSdk> =
|
||||
filterSuggestedPaths(VirtualEnvSdkFlavor.getInstance(), existingSdks, module, context)
|
||||
|
||||
@Internal
|
||||
|
||||
fun filterSharedCondaEnvs(module: Module?, existingSdks: List<Sdk>): List<Sdk> {
|
||||
return existingSdks.filter { it.sdkType is PythonSdkType && PythonSdkUtil.isConda(it) && !it.isAssociatedWithAnotherModule(module) }
|
||||
}
|
||||
|
||||
@Internal
|
||||
|
||||
fun filterAssociatedSdks(module: Module, existingSdks: List<Sdk>): List<Sdk> {
|
||||
return existingSdks.filter { it.sdkType is PythonSdkType && it.isAssociatedWithModule(module) }
|
||||
}
|
||||
|
||||
@Internal
|
||||
|
||||
fun detectAssociatedEnvironments(module: Module, existingSdks: List<Sdk>, context: UserDataHolder): List<PyDetectedSdk> =
|
||||
detectVirtualEnvs(module, existingSdks, context).filter { it.isAssociatedWithModule(module) }
|
||||
|
||||
@@ -164,6 +172,8 @@ fun createSdkByGenerateTask(
|
||||
suggestedSdkName: String?,
|
||||
): Sdk = createSdkByGenerateTask(generateSdkHomePath, existingSdks, baseSdk, associatedProjectPath, suggestedSdkName, null)
|
||||
|
||||
@Internal
|
||||
|
||||
fun createSdkByGenerateTask(
|
||||
generateSdkHomePath: Task.WithResult<String, ExecutionException>,
|
||||
existingSdks: List<Sdk>,
|
||||
@@ -238,6 +248,8 @@ fun showSdkExecutionException(sdk: Sdk?, e: ExecutionException, @NlsContexts.Dia
|
||||
}
|
||||
}
|
||||
|
||||
@Internal
|
||||
|
||||
fun Sdk.isAssociatedWithModule(module: Module?): Boolean {
|
||||
val basePath = module?.basePath
|
||||
val associatedPath = associatedModulePath
|
||||
@@ -246,6 +258,8 @@ fun Sdk.isAssociatedWithModule(module: Module?): Boolean {
|
||||
return isLocatedInsideModule(module) || containsModuleName(module)
|
||||
}
|
||||
|
||||
@Internal
|
||||
|
||||
fun Sdk.isAssociatedWithAnotherModule(module: Module?): Boolean {
|
||||
val basePath = module?.basePath ?: return false
|
||||
val associatedPath = associatedModulePath ?: return false
|
||||
@@ -274,6 +288,8 @@ internal fun PyDetectedSdk.setupAssociatedLogged(existingSdks: List<Sdk>, associ
|
||||
return setupAssociated(existingSdks, associatedModulePath, doAssociate).getOrLogException(LOGGER)
|
||||
}
|
||||
|
||||
@Internal
|
||||
|
||||
fun PyDetectedSdk.setupAssociated(existingSdks: List<Sdk>, associatedModulePath: String?, doAssociate: Boolean): Result<Sdk> {
|
||||
if (!sdkSeemsValid) {
|
||||
return failure("sdk is not valid")
|
||||
@@ -343,6 +359,8 @@ var Project.pythonSdk: Sdk?
|
||||
}
|
||||
}
|
||||
|
||||
@Internal
|
||||
|
||||
fun Module.excludeInnerVirtualEnv(sdk: Sdk) {
|
||||
val root = getInnerVirtualEnvRoot(sdk) ?: return
|
||||
|
||||
@@ -366,6 +384,8 @@ fun Project.excludeInnerVirtualEnv(sdk: Sdk) {
|
||||
ModuleUtil.findModuleForFile(binary, this)?.excludeInnerVirtualEnv(sdk)
|
||||
}
|
||||
|
||||
@Internal
|
||||
|
||||
fun getInnerVirtualEnvRoot(sdk: Sdk): VirtualFile? {
|
||||
val binaryPath = sdk.homePath ?: return null
|
||||
|
||||
@@ -416,6 +436,8 @@ private val Sdk.sitePackagesDirectory: VirtualFile?
|
||||
|
||||
val Sdk.sdkFlavor: PythonSdkFlavor<*> get() = getOrCreateAdditionalData().flavor
|
||||
|
||||
@Internal
|
||||
|
||||
fun Sdk.isLocatedInsideModule(module: Module?): Boolean {
|
||||
val moduleDir = module?.baseDir
|
||||
val sdkDir = homeDirectory
|
||||
@@ -504,6 +526,8 @@ val Sdk.remoteSourcesLocalPath: Path
|
||||
/**
|
||||
* Configures [targetCommandLineBuilder] (sets a binary path and other stuff) so it could run python on this target
|
||||
*/
|
||||
@Internal
|
||||
|
||||
fun Sdk.configureBuilderToRunPythonOnTarget(targetCommandLineBuilder: TargetedCommandLineBuilder) {
|
||||
getOrCreateAdditionalData().flavorAndData.data.prepareTargetCommandLine(this, targetCommandLineBuilder)
|
||||
}
|
||||
|
||||
@@ -1,18 +1,4 @@
|
||||
/*
|
||||
* Copyright 2000-2014 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the 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.jetbrains.python.sdk
|
||||
|
||||
import com.intellij.openapi.projectRoots.Sdk
|
||||
@@ -23,8 +9,10 @@ import org.jetbrains.annotations.Nls
|
||||
import java.awt.Component
|
||||
import javax.swing.JList
|
||||
|
||||
open class PySdkListCellRenderer @JvmOverloads constructor(@Nls private val nullSdkName: String = noInterpreterMarker,
|
||||
private val nullSdkValue: Sdk? = null) : ColoredListCellRenderer<Any>() {
|
||||
class PySdkListCellRenderer @JvmOverloads constructor(
|
||||
@Nls private val nullSdkName: String = noInterpreterMarker,
|
||||
private val nullSdkValue: Sdk? = null,
|
||||
) : ColoredListCellRenderer<Any>() {
|
||||
|
||||
override fun getListCellRendererComponent(list: JList<out Any>?, value: Any?, index: Int, selected: Boolean,
|
||||
hasFocus: Boolean): Component =
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
// Copyright 2000-2025 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.icons.AllIcons
|
||||
@@ -13,16 +13,21 @@ import com.intellij.ui.SimpleTextAttributes
|
||||
import com.jetbrains.python.PyBundle
|
||||
import com.jetbrains.python.psi.LanguageLevel
|
||||
import com.jetbrains.python.sdk.flavors.PythonSdkFlavor
|
||||
import org.jetbrains.annotations.ApiStatus
|
||||
import org.jetbrains.annotations.Nls
|
||||
import javax.swing.Icon
|
||||
|
||||
val noInterpreterMarker: String = "<${PyBundle.message("python.sdk.there.is.no.interpreter")}>"
|
||||
|
||||
@ApiStatus.Internal
|
||||
|
||||
fun name(sdk: Sdk): Triple<String?, String, String?> = name(sdk, sdk.name)
|
||||
|
||||
/**
|
||||
* Returns modifier that shortly describes that is wrong with passed [sdk], [name] and additional info.
|
||||
*/
|
||||
@ApiStatus.Internal
|
||||
|
||||
fun name(sdk: Sdk, name: String): Triple<String?, String, String?> {
|
||||
val modifier = when {
|
||||
!sdk.sdkSeemsValid || PythonSdkType.hasInvalidRemoteCredentials(sdk) -> "invalid"
|
||||
@@ -47,6 +52,8 @@ fun name(sdk: Sdk, name: String): Triple<String?, String, String?> {
|
||||
*
|
||||
* @see FileUtil.getLocationRelativeToUserHome
|
||||
*/
|
||||
@ApiStatus.Internal
|
||||
|
||||
fun path(sdk: Sdk): @NlsSafe String? {
|
||||
val name = sdk.name
|
||||
val homePath = sdk.homePath ?: return null
|
||||
@@ -73,6 +80,8 @@ fun path(sdk: Sdk): @NlsSafe String? {
|
||||
* @see PythonSdkType.hasInvalidRemoteCredentials
|
||||
* @see LanguageLevel.SUPPORTED_LEVELS
|
||||
*/
|
||||
@ApiStatus.Internal
|
||||
|
||||
fun icon(sdk: Sdk): Icon {
|
||||
val flavor: PythonSdkFlavor<*> = sdk.getOrCreateAdditionalData().flavor
|
||||
|
||||
@@ -104,6 +113,8 @@ fun icon(sdk: Sdk): Icon {
|
||||
* @see PythonSdkUtil.isRemote
|
||||
* @see PyRenderedSdkType
|
||||
*/
|
||||
@ApiStatus.Internal
|
||||
|
||||
fun groupModuleSdksByTypes(allSdks: List<Sdk>, module: Module?, invalid: (Sdk) -> Boolean): Map<PyRenderedSdkType, List<Sdk>> {
|
||||
return allSdks
|
||||
.asSequence()
|
||||
@@ -122,6 +133,8 @@ fun groupModuleSdksByTypes(allSdks: List<Sdk>, module: Module?, invalid: (Sdk) -
|
||||
*
|
||||
* @see groupModuleSdksByTypes
|
||||
*/
|
||||
@ApiStatus.Internal
|
||||
|
||||
enum class PyRenderedSdkType {
|
||||
VIRTUALENV, SYSTEM, REMOTE
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2000-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
// Copyright 2000-2025 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.execution.ExecutionException
|
||||
@@ -12,9 +12,15 @@ import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.projectRoots.Sdk
|
||||
import com.intellij.openapi.util.Disposer
|
||||
import com.jetbrains.python.PythonHelper
|
||||
import com.jetbrains.python.run.*
|
||||
import com.jetbrains.python.run.PythonInterpreterTargetEnvironmentFactory
|
||||
import com.jetbrains.python.run.buildTargetedCommandLine
|
||||
import com.jetbrains.python.run.execute
|
||||
import com.jetbrains.python.run.prepareHelperScriptExecution
|
||||
import com.jetbrains.python.run.target.HelpersAwareTargetEnvironmentRequest
|
||||
import com.jetbrains.python.sdk.flavors.PythonSdkFlavor
|
||||
import org.jetbrains.annotations.ApiStatus
|
||||
|
||||
@ApiStatus.Internal
|
||||
|
||||
class PyTargetsIntrospectionFacade(val sdk: Sdk, val project: Project) {
|
||||
private val pyRequest: HelpersAwareTargetEnvironmentRequest =
|
||||
@@ -34,7 +40,7 @@ class PyTargetsIntrospectionFacade(val sdk: Sdk, val project: Project) {
|
||||
// PythonExecution doesn't support launching a bare interpreter without a script or module
|
||||
val cmdBuilder = TargetedCommandLineBuilder(targetEnvRequest)
|
||||
sdk.configureBuilderToRunPythonOnTarget(cmdBuilder)
|
||||
val sdkFlavor = sdk.sdkFlavor
|
||||
sdk.sdkFlavor
|
||||
cmdBuilder.addParameter(PythonSdkFlavor.PYTHON_VERSION_ARG)
|
||||
val cmd = cmdBuilder.build()
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2000-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
// Copyright 2000-2025 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.google.gson.Gson
|
||||
@@ -32,6 +32,7 @@ import com.jetbrains.python.run.target.HelpersAwareTargetEnvironmentRequest
|
||||
import com.jetbrains.python.target.PyTargetAwareAdditionalData
|
||||
import com.jetbrains.python.target.PyTargetAwareAdditionalData.Companion.pathsAddedByUser
|
||||
import com.jetbrains.python.target.PyTargetAwareAdditionalData.Companion.pathsRemovedByUser
|
||||
import org.jetbrains.annotations.ApiStatus
|
||||
import java.nio.file.Files
|
||||
import java.nio.file.attribute.FileTime
|
||||
import java.nio.file.attribute.PosixFilePermissions
|
||||
@@ -43,6 +44,8 @@ import kotlin.io.path.setPosixFilePermissions
|
||||
|
||||
private const val STATE_FILE = ".state.json"
|
||||
|
||||
@ApiStatus.Internal
|
||||
|
||||
class PyTargetsRemoteSourcesRefresher(val sdk: Sdk, private val project: Project) {
|
||||
private val pyRequest: HelpersAwareTargetEnvironmentRequest =
|
||||
checkNotNull(PythonInterpreterTargetEnvironmentFactory.findPythonTargetInterpreter(sdk, project))
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
// Copyright 2000-2025 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.google.common.collect.MultimapBuilder
|
||||
@@ -16,10 +16,13 @@ import com.intellij.openapi.util.registry.Registry
|
||||
import com.intellij.openapi.vfs.VfsUtil
|
||||
import com.intellij.openapi.vfs.VirtualFile
|
||||
import com.jetbrains.python.psi.PyUtil
|
||||
import org.jetbrains.annotations.ApiStatus
|
||||
|
||||
/**
|
||||
* Applies [transferRoots] to all modules having [sdk] as a python sdk.
|
||||
*/
|
||||
@ApiStatus.Internal
|
||||
|
||||
fun transferRootsToModulesWithSdk(project: Project, sdk: Sdk) {
|
||||
updateRootsForModulesWithSdk(project, sdk, ::transferRoots)
|
||||
}
|
||||
@@ -27,6 +30,8 @@ fun transferRootsToModulesWithSdk(project: Project, sdk: Sdk) {
|
||||
/**
|
||||
* See [transferRootsToModulesWithSdk] and [removeTransferredRoots].
|
||||
*/
|
||||
@ApiStatus.Internal
|
||||
|
||||
fun removeTransferredRootsFromModulesWithSdk(project: Project, sdk: Sdk) {
|
||||
updateRootsForModulesWithSdk(project, sdk, ::removeTransferredRoots)
|
||||
}
|
||||
@@ -44,6 +49,8 @@ private fun updateRootsForModulesWithSdk(project: Project, sdk: Sdk?, action: (M
|
||||
/**
|
||||
* Applies [transferRoots] to all modules inheriting python sdk from the [project].
|
||||
*/
|
||||
@ApiStatus.Internal
|
||||
|
||||
fun transferRootsToModulesWithInheritedSdk(project: Project, sdk: Sdk?) {
|
||||
updateRootsForModulesWithInheritedSdk(project, sdk, ::transferRoots)
|
||||
}
|
||||
@@ -51,6 +58,8 @@ fun transferRootsToModulesWithInheritedSdk(project: Project, sdk: Sdk?) {
|
||||
/**
|
||||
* See [transferRootsToModulesWithInheritedSdk] and [removeTransferredRoots].
|
||||
*/
|
||||
@ApiStatus.Internal
|
||||
|
||||
fun removeTransferredRootsFromModulesWithInheritedSdk(project: Project, sdk: Sdk?) {
|
||||
updateRootsForModulesWithInheritedSdk(project, sdk, ::removeTransferredRoots)
|
||||
}
|
||||
@@ -59,10 +68,14 @@ fun removeTransferredRootsFromModulesWithInheritedSdk(project: Project, sdk: Sdk
|
||||
* Returns [sdk] paths that are located under project modules and hence should be turned into source roots,
|
||||
* at least to avoid enabling reader mode for them.
|
||||
*/
|
||||
@ApiStatus.Internal
|
||||
|
||||
fun getPathsToTransfer(sdk: Sdk): Set<VirtualFile> {
|
||||
return (sdk.sdkAdditionalData as? PythonSdkAdditionalData)?.pathsToTransfer ?: emptySet()
|
||||
}
|
||||
|
||||
@ApiStatus.Internal
|
||||
|
||||
fun setPathsToTransfer(sdk: Sdk, roots: Set<VirtualFile>) {
|
||||
runInEdt {
|
||||
if (roots.isNotEmpty() || getPathsToTransfer(sdk).isNotEmpty()) { // do not create additional data with no reason
|
||||
@@ -78,6 +91,8 @@ fun setPathsToTransfer(sdk: Sdk, roots: Set<VirtualFile>) {
|
||||
/**
|
||||
* Turns [getPathsToTransfer] result into [module] source roots and dependencies if [module] python sdk is [sdk].
|
||||
*/
|
||||
@ApiStatus.Internal
|
||||
|
||||
fun transferRoots(module: Module, sdk: Sdk?) {
|
||||
if (sdk != null && module.pythonSdk == sdk) {
|
||||
runInEdt {
|
||||
@@ -98,6 +113,8 @@ private fun addTransferredRoots(module: Module, newTransferredRoots: ModuleTrans
|
||||
/**
|
||||
* Removes [getPathsToTransfer] result from [module] source roots and dependencies if [module] python sdk is [sdk].
|
||||
*/
|
||||
@ApiStatus.Internal
|
||||
|
||||
fun removeTransferredRoots(module: Module, sdk: Sdk?) {
|
||||
if (sdk != null && module.pythonSdk == sdk) {
|
||||
runInEdt {
|
||||
@@ -115,6 +132,8 @@ private fun removeTransferredRoots(module: Module, newTransferredRoots: ModuleTr
|
||||
PyUtil.removeModuleDependencies(module, newTransferredRoots.dependencies)
|
||||
}
|
||||
|
||||
@ApiStatus.Internal
|
||||
|
||||
fun updateTransferredRoots(project: Project, sdk: Sdk, newInProjectPaths: Set<VirtualFile>) {
|
||||
val rootsDetector = TransferredRootsDetector(project)
|
||||
val modulesWithThisSdk = rootsDetector.projectModules.filter { it.pythonSdk == sdk }
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
// Copyright 2000-2025 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.openapi.actionSystem.ActionUpdateThread;
|
||||
@@ -10,8 +10,11 @@ import com.intellij.openapi.module.ModuleManager;
|
||||
import com.intellij.openapi.project.DumbAwareAction;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.projectRoots.Sdk;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
@ApiStatus.Internal
|
||||
|
||||
public class PyUpdateProjectSdkAction extends DumbAwareAction {
|
||||
private static final Logger LOG = Logger.getInstance(PyUpdateProjectSdkAction.class);
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// 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.jetbrains.python.sdk
|
||||
|
||||
import com.intellij.openapi.application.runReadAction
|
||||
@@ -17,7 +17,7 @@ import com.intellij.ui.dsl.builder.Panel
|
||||
import com.intellij.ui.dsl.builder.bindSelected
|
||||
import com.jetbrains.python.PyBundle
|
||||
|
||||
class PyVirtualEnvVcsCustomizer : VcsEnvCustomizer() {
|
||||
internal class PyVirtualEnvVcsCustomizer : VcsEnvCustomizer() {
|
||||
override fun customizeCommandAndEnvironment(project: Project?, envs: MutableMap<String, String>, context: VcsExecutableContext) {
|
||||
if (project == null || !PyVirtualEnvVcsSettings.getInstance(project).virtualEnvActivate) return
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2000-2023 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.jetbrains.python.sdk
|
||||
|
||||
import com.intellij.openapi.application.ApplicationManager
|
||||
@@ -10,9 +10,12 @@ import com.intellij.openapi.startup.ProjectActivity
|
||||
import com.intellij.openapi.util.text.StringUtil
|
||||
import com.jetbrains.python.PyBundle
|
||||
import kotlinx.coroutines.delay
|
||||
import org.jetbrains.annotations.ApiStatus
|
||||
import kotlin.time.Duration.Companion.seconds
|
||||
|
||||
class PythonHeadlessSdkUpdater : ProjectActivity, DumbAware {
|
||||
@ApiStatus.Internal
|
||||
|
||||
internal class PythonHeadlessSdkUpdater : ProjectActivity, DumbAware {
|
||||
private val DELAY = 10.seconds
|
||||
|
||||
companion object {
|
||||
|
||||
@@ -1,12 +1,15 @@
|
||||
// Copyright 2000-2022 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.jetbrains.python.sdk
|
||||
|
||||
import com.google.gson.*
|
||||
import org.jetbrains.annotations.ApiStatus
|
||||
import java.lang.reflect.Type
|
||||
|
||||
/**
|
||||
* Mark sealed class to serialize automatically each inheritor
|
||||
*/
|
||||
@ApiStatus.Internal
|
||||
|
||||
class SealedClassAdapter : JsonSerializer<Any>, JsonDeserializer<Any> {
|
||||
private companion object {
|
||||
const val sealedClassChildId = "sealedClassChildId"
|
||||
|
||||
@@ -1,41 +0,0 @@
|
||||
// Copyright 2000-2023 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.execution.target.TargetEnvironmentConfiguration
|
||||
import com.intellij.openapi.util.Key
|
||||
import com.intellij.openapi.util.UserDataHolder
|
||||
import com.intellij.openapi.util.UserDataHolderBase
|
||||
|
||||
val TARGET_CONTEXTS_KEY = Key.create<TargetStorage>("TARGET_CONTEXTS")
|
||||
|
||||
fun <T> UserDataHolder.getUserData(configuration: TargetEnvironmentConfiguration?, key: Key<T>): T? {
|
||||
val targetStorage = getUserData(TARGET_CONTEXTS_KEY) ?: TargetStorage().also { putUserData(TARGET_CONTEXTS_KEY, it) }
|
||||
return targetStorage.getUserData(configuration, key)
|
||||
}
|
||||
|
||||
fun <T> UserDataHolder.putUserData(configuration: TargetEnvironmentConfiguration?, key: Key<T>, value: T?) {
|
||||
val targetStorage = getUserData(TARGET_CONTEXTS_KEY) ?: TargetStorage().also { putUserData(TARGET_CONTEXTS_KEY, it) }
|
||||
targetStorage.putUserData(configuration, key, value)
|
||||
}
|
||||
|
||||
/**
|
||||
* This class stores information for a specific target.
|
||||
*/
|
||||
class TargetStorage {
|
||||
private val context = mutableMapOf<Id, UserDataHolder>()
|
||||
|
||||
fun <T> getUserData(configuration: TargetEnvironmentConfiguration?, key: Key<T>): T? = context[configuration.getId()]?.getUserData(key)
|
||||
|
||||
fun <T> putUserData(configuration: TargetEnvironmentConfiguration?, key: Key<T>, value: T?): Unit =
|
||||
context.computeIfAbsent(configuration.getId()) { UserDataHolderBase() }.putUserData(key, value)
|
||||
|
||||
private sealed class Id
|
||||
|
||||
private data object LocalMachineId : Id()
|
||||
|
||||
private data class TargetId(val id: String) : Id()
|
||||
|
||||
companion object {
|
||||
private fun TargetEnvironmentConfiguration?.getId() = if (this == null) LocalMachineId else TargetId(uuid)
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,13 @@
|
||||
// Copyright 2000-2023 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.jetbrains.python.sdk.add.collector
|
||||
|
||||
import com.intellij.internal.statistic.eventLog.EventLogGroup
|
||||
import com.intellij.internal.statistic.service.fus.collectors.CounterUsagesCollector
|
||||
import com.intellij.openapi.projectRoots.Sdk
|
||||
import com.jetbrains.python.statistics.*
|
||||
import org.jetbrains.annotations.ApiStatus
|
||||
|
||||
@ApiStatus.Internal
|
||||
|
||||
object PythonNewInterpreterAddedCollector : CounterUsagesCollector() {
|
||||
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
@ApiStatus.Internal
|
||||
package com.jetbrains.python.sdk.add.v2.conda;
|
||||
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
@@ -0,0 +1,5 @@
|
||||
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
@ApiStatus.Internal
|
||||
package com.jetbrains.python.sdk.add.v2.hatch;
|
||||
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
@@ -0,0 +1,5 @@
|
||||
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
@ApiStatus.Internal
|
||||
package com.jetbrains.python.sdk.add.v2.poetry;
|
||||
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
@@ -0,0 +1,5 @@
|
||||
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
@ApiStatus.Internal
|
||||
package com.jetbrains.python.sdk.add.v2.uv;
|
||||
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
@@ -0,0 +1,5 @@
|
||||
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
@ApiStatus.Internal
|
||||
package com.jetbrains.python.sdk.conda;
|
||||
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
@@ -0,0 +1,5 @@
|
||||
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
@ApiStatus.Internal
|
||||
package com.jetbrains.python.sdk.configuration;
|
||||
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2000-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
// Copyright 2000-2025 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;
|
||||
|
||||
import com.intellij.execution.ExecutionException;
|
||||
@@ -16,6 +16,7 @@ import com.intellij.openapi.util.text.HtmlChunk;
|
||||
import com.intellij.util.concurrency.annotations.RequiresBackgroundThread;
|
||||
import com.jetbrains.python.PyBundle;
|
||||
import com.jetbrains.python.sdk.PyDetectedSdk;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -28,6 +29,7 @@ import java.util.Set;
|
||||
import static com.intellij.openapi.util.text.HtmlChunk.raw;
|
||||
import static com.intellij.openapi.util.text.HtmlChunk.text;
|
||||
|
||||
@ApiStatus.Internal
|
||||
|
||||
public final class MacPythonSdkFlavor extends CPythonSdkFlavor<PyFlavorData.Empty> {
|
||||
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
// Copyright 2000-2025 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
|
||||
|
||||
import com.intellij.openapi.util.io.FileUtil
|
||||
import com.intellij.openapi.vfs.VirtualFile
|
||||
import org.jetbrains.annotations.ApiStatus
|
||||
import java.io.File
|
||||
|
||||
@ApiStatus.Internal
|
||||
|
||||
class MayaSdkFlavor private constructor() : CPythonSdkFlavor<PyFlavorData.Empty>() {
|
||||
override fun getFlavorDataClass(): Class<PyFlavorData.Empty> = PyFlavorData.Empty::class.java
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2000-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
// Copyright 2000-2025 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;
|
||||
|
||||
import com.google.common.collect.Sets;
|
||||
@@ -19,6 +19,8 @@ import java.util.*;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@ApiStatus.Internal
|
||||
|
||||
|
||||
public final class UnixPythonSdkFlavor extends CPythonSdkFlavor<PyFlavorData.Empty> {
|
||||
private static final String[] BIN_DIRECTORIES = new String[]{"/usr/bin", "/usr/local/bin"};
|
||||
@@ -55,9 +57,7 @@ public final class UnixPythonSdkFlavor extends CPythonSdkFlavor<PyFlavorData.Emp
|
||||
|
||||
public static @NotNull List<Path> getDefaultUnixPythons(@Nullable Path rootPath) {
|
||||
var candidates = new ArrayList<Path>();
|
||||
Arrays.stream(BIN_DIRECTORIES)
|
||||
.map(Path::of)
|
||||
.map(binDirectory -> optionallyChangeRoot(rootPath, binDirectory))
|
||||
Arrays.stream(BIN_DIRECTORIES).map(Path::of).map(binDirectory -> optionallyChangeRoot(rootPath, binDirectory))
|
||||
.forEach(rootDir -> collectUnixPythons(rootDir, candidates));
|
||||
|
||||
collectPyenvPythons(candidates);
|
||||
@@ -73,10 +73,7 @@ public final class UnixPythonSdkFlavor extends CPythonSdkFlavor<PyFlavorData.Emp
|
||||
public static void collectUnixPythons(@NotNull Path binDirectory, @NotNull Collection<Path> candidates) {
|
||||
try (var entries = Files.list(binDirectory)) {
|
||||
// Hack to exclude system python2
|
||||
entries
|
||||
.filter(path ->
|
||||
ContainerUtil.exists(SYS_PYTHON_FILE_NAMES, regex -> regex.matcher(path.getFileName().toString()).matches())
|
||||
)
|
||||
entries.filter(path -> ContainerUtil.exists(SYS_PYTHON_FILE_NAMES, regex -> regex.matcher(path.getFileName().toString()).matches()))
|
||||
.collect(Collectors.toCollection(() -> candidates));
|
||||
}
|
||||
catch (IOException ignored) {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// 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.jetbrains.python.sdk.flavors;
|
||||
|
||||
import com.intellij.openapi.application.ReadAction;
|
||||
@@ -13,6 +13,7 @@ import com.jetbrains.python.sdk.BasePySdkExtKt;
|
||||
import com.jetbrains.python.sdk.PySdkExtKt;
|
||||
import com.jetbrains.python.sdk.PythonSdkUtil;
|
||||
import com.jetbrains.python.venvReader.VirtualEnvReader;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -24,6 +25,8 @@ import java.util.Collection;
|
||||
/**
|
||||
* User : catherine
|
||||
*/
|
||||
@ApiStatus.Internal
|
||||
|
||||
public final class VirtualEnvSdkFlavor extends CPythonSdkFlavor<PyFlavorData.Empty> {
|
||||
private VirtualEnvSdkFlavor() {
|
||||
}
|
||||
|
||||
@@ -34,6 +34,8 @@ import static com.jetbrains.python.venvReader.ResolveUtilKt.tryResolvePath;
|
||||
* This class knows how to find python in Windows Registry according to
|
||||
* <a href="https://www.python.org/dev/peps/pep-0514/">PEP 514</a>
|
||||
*/
|
||||
@ApiStatus.Internal
|
||||
|
||||
public class WinPythonSdkFlavor extends CPythonSdkFlavor<PyFlavorData.Empty> {
|
||||
private static final @NotNull String[] REG_ROOTS = {"HKEY_LOCAL_MACHINE", "HKEY_CURRENT_USER"};
|
||||
/**
|
||||
|
||||
@@ -1,27 +1,16 @@
|
||||
/*
|
||||
* Copyright 2000-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the 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.jetbrains.python.sdk.flavors
|
||||
|
||||
import com.intellij.openapi.util.io.WindowsRegistryUtil
|
||||
import org.jetbrains.annotations.ApiStatus
|
||||
|
||||
/**
|
||||
* Win registry access service
|
||||
*
|
||||
* @author Ilya.Kazakevich
|
||||
*/
|
||||
@ApiStatus.Internal
|
||||
|
||||
interface WinRegistryService {
|
||||
/**
|
||||
* @param basePath path like "HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node"
|
||||
@@ -36,7 +25,7 @@ interface WinRegistryService {
|
||||
fun getDefaultKey(path: String): String?
|
||||
}
|
||||
|
||||
class WinRegistryServiceImpl : WinRegistryService {
|
||||
internal class WinRegistryServiceImpl : WinRegistryService {
|
||||
override fun listBranches(basePath: String): List<String> = WindowsRegistryUtil.readRegistryBranch(basePath)
|
||||
|
||||
override fun getDefaultKey(path: String): String? = WindowsRegistryUtil.readRegistryDefault(path)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2000-2022 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.jetbrains.python.sdk.flavors.conda
|
||||
|
||||
import com.intellij.execution.Platform
|
||||
@@ -9,6 +9,7 @@ import com.intellij.openapi.projectRoots.Sdk
|
||||
import com.intellij.util.EnvReader
|
||||
import com.jetbrains.python.sdk.PySdkUtil
|
||||
import com.jetbrains.python.sdk.getOrCreateAdditionalData
|
||||
import org.jetbrains.annotations.ApiStatus
|
||||
import java.io.IOException
|
||||
import java.nio.file.Path
|
||||
import kotlin.io.path.exists
|
||||
@@ -24,7 +25,7 @@ private val LOG = Logger.getInstance("CondaLogger")
|
||||
*
|
||||
* Non-conda, non-local and non-windows command lines are silently ignored
|
||||
* */
|
||||
|
||||
@ApiStatus.Internal
|
||||
fun TargetedCommandLineBuilder.fixCondaPathEnvIfNeeded(sdk: Sdk) {
|
||||
if (!localOnWindows) return
|
||||
val condaData = (sdk.getOrCreateAdditionalData().flavorAndData.data as? PyCondaFlavorData) ?: return
|
||||
@@ -36,6 +37,8 @@ fun TargetedCommandLineBuilder.fixCondaPathEnvIfNeeded(sdk: Sdk) {
|
||||
addEnvVars(PySdkUtil.activateVirtualEnv(sdk), condaData.env.fullCondaPathOnTarget)
|
||||
}
|
||||
|
||||
@ApiStatus.Internal
|
||||
|
||||
fun TargetedCommandLineBuilder.fixCondaPathEnvIfNeeded(condaPathOnTarget: FullPathOnTarget) {
|
||||
if (!localOnWindows) return
|
||||
val condaPath = Path.of(condaPathOnTarget)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2000-2022 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.jetbrains.python.sdk.flavors.conda
|
||||
|
||||
import com.intellij.execution.target.TargetedCommandLineBuilder
|
||||
@@ -6,6 +6,7 @@ import com.intellij.openapi.diagnostic.Logger
|
||||
import com.intellij.openapi.projectRoots.Sdk
|
||||
import com.intellij.openapi.util.registry.Registry
|
||||
import com.jetbrains.python.packaging.getCondaBasePython
|
||||
import org.jetbrains.annotations.ApiStatus
|
||||
import java.nio.file.Path
|
||||
import kotlin.io.path.isExecutable
|
||||
|
||||
@@ -21,6 +22,8 @@ val usePythonForLocalConda: Boolean get() = Registry.`is`("use.python.for.local.
|
||||
* For the legacy it either takes homePath from [sdk] or base conda but from the base env only.
|
||||
* So, you should provide sdk or (if you do not have it) base conda env. Otherwise, fallbacks to "conda run" even in legacy mode
|
||||
*/
|
||||
|
||||
@ApiStatus.Internal
|
||||
fun addCondaPythonToTargetCommandLine(targetedCommandLineBuilder: TargetedCommandLineBuilder,
|
||||
condaEnv: PyCondaEnv,
|
||||
sdk: Sdk?) {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2000-2023 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.jetbrains.python.sdk.flavors.conda
|
||||
|
||||
import com.intellij.execution.process.*
|
||||
@@ -15,7 +15,7 @@ import kotlin.coroutines.CoroutineContext
|
||||
*
|
||||
* You could either start [ProcessHandler.startNotify] manually, use constructor that wraps process or use [runProcessAndGetError].
|
||||
*/
|
||||
class ProcessHandlerReader(processHandler: ProcessHandler) {
|
||||
internal class ProcessHandlerReader(processHandler: ProcessHandler) {
|
||||
private val stdOutImpl: Channel<String> = Channel()
|
||||
private val stdErrImpl: Channel<String> = Channel()
|
||||
private val processResult: Channel<Int> = Channel()
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2000-2022 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.jetbrains.python.sdk.flavors.conda
|
||||
|
||||
import com.intellij.execution.target.*
|
||||
@@ -8,10 +8,13 @@ import com.intellij.util.concurrency.annotations.RequiresBackgroundThread
|
||||
import com.jetbrains.python.pathValidation.PlatformAndRoot.Companion.getPlatformAndRoot
|
||||
import com.jetbrains.python.pathValidation.ValidationRequest
|
||||
import com.jetbrains.python.pathValidation.validateExecutableFile
|
||||
import org.jetbrains.annotations.ApiStatus
|
||||
|
||||
/**
|
||||
* Encapsulates conda binary command to simplify target request creation
|
||||
*/
|
||||
@ApiStatus.Internal
|
||||
|
||||
class PyCondaCommand(
|
||||
val fullCondaPathOnTarget: FullPathOnTarget,
|
||||
internal val targetConfig: TargetEnvironmentConfiguration?,
|
||||
|
||||
@@ -27,6 +27,8 @@ import kotlin.io.path.exists
|
||||
* TODO: Once we get rid of [TargetCommandExecutor] and have access to [com.intellij.execution.target.TargetEnvironmentConfiguration] use it validate conda binary in [getEnvs]
|
||||
* @see `PyCondaTest`
|
||||
*/
|
||||
@ApiStatus.Internal
|
||||
|
||||
data class PyCondaEnv(
|
||||
val envIdentity: PyCondaEnvIdentity,
|
||||
val fullCondaPathOnTarget: FullPathOnTarget,
|
||||
|
||||
@@ -1,15 +1,17 @@
|
||||
// Copyright 2000-2022 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.jetbrains.python.sdk.flavors.conda
|
||||
|
||||
import com.google.gson.annotations.JsonAdapter
|
||||
import com.intellij.execution.target.FullPathOnTarget
|
||||
import com.jetbrains.python.sdk.SealedClassAdapter
|
||||
import org.jetbrains.annotations.ApiStatus
|
||||
|
||||
|
||||
/**
|
||||
* Conda environment could be either named or unnamed (based on path).
|
||||
* [userReadableName] used as sdk name
|
||||
*/
|
||||
@ApiStatus.Internal
|
||||
@JsonAdapter(SealedClassAdapter::class)
|
||||
sealed class PyCondaEnvIdentity(val userReadableName: String) {
|
||||
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
// Copyright 2000-2022 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.jetbrains.python.sdk.flavors.conda
|
||||
|
||||
import com.intellij.execution.target.TargetedCommandLineBuilder
|
||||
import com.intellij.openapi.projectRoots.Sdk
|
||||
import com.jetbrains.python.sdk.flavors.PyFlavorData
|
||||
import org.jetbrains.annotations.ApiStatus
|
||||
|
||||
@ApiStatus.Internal
|
||||
|
||||
data class PyCondaFlavorData(val env: PyCondaEnv) : PyFlavorData {
|
||||
override fun prepareTargetCommandLine(sdk: Sdk, targetCommandLineBuilder: TargetedCommandLineBuilder) {
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
@ApiStatus.Internal
|
||||
package com.jetbrains.python.sdk.pipenv;
|
||||
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
@@ -0,0 +1,5 @@
|
||||
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
@ApiStatus.Internal
|
||||
package com.jetbrains.python.sdk.pipenv.quickFixes;
|
||||
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
@@ -0,0 +1,5 @@
|
||||
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
@ApiStatus.Internal
|
||||
package com.jetbrains.python.sdk.pipenv.ui;
|
||||
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
@@ -0,0 +1,5 @@
|
||||
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
@ApiStatus.Internal
|
||||
package com.jetbrains.python.sdk.poetry.quickFixes;
|
||||
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
@@ -0,0 +1,5 @@
|
||||
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
@ApiStatus.Internal
|
||||
package com.jetbrains.python.sdk.poetry.ui;
|
||||
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
@@ -0,0 +1,5 @@
|
||||
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
@ApiStatus.Internal
|
||||
package com.jetbrains.python.sdk.skeletons;
|
||||
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
@@ -0,0 +1,5 @@
|
||||
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
@ApiStatus.Internal
|
||||
package com.jetbrains.python.sdk.uv.impl;
|
||||
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
5
python/src/com/jetbrains/python/sdk/uv/package-info.java
Normal file
5
python/src/com/jetbrains/python/sdk/uv/package-info.java
Normal file
@@ -0,0 +1,5 @@
|
||||
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
@ApiStatus.Internal
|
||||
package com.jetbrains.python.sdk.uv;
|
||||
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
@@ -0,0 +1,5 @@
|
||||
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
@ApiStatus.Internal
|
||||
package com.jetbrains.python.sdk.uv.run;
|
||||
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
@@ -0,0 +1,5 @@
|
||||
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
@ApiStatus.Internal
|
||||
package com.jetbrains.python.sdk.uv.ui;
|
||||
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
Reference in New Issue
Block a user