[python] Code Review Changes(PY-60410)

GitOrigin-RevId: c4054e33a65db334dd5c9c2a7e2e6a9b38766eb2
This commit is contained in:
Vitaly Legchilkin
2025-03-12 20:49:14 +00:00
committed by intellij-monorepo-bot
parent a53a6fce7c
commit 388604d4a9
6 changed files with 31 additions and 11 deletions
@@ -59,6 +59,7 @@ sdk.notification.label.set.up.poetry.environment.from.pyproject.toml.dependencie
notification.group.pro.advertiser=PyCharm Professional recommended
sdk.set.up.hatch.environment=Set up Hatch 'default' environment
sdk.set.up.hatch.project.analysis=Hatch project analysis
sdk.set.up.uv.environment=Set up an uv environment using {0}
new.project.python.group.name=Python
@@ -13,17 +13,20 @@ import com.intellij.python.hatch.getHatchService
import com.intellij.util.concurrency.annotations.RequiresBackgroundThread
import com.jetbrains.python.getOrNull
import com.jetbrains.python.orLogException
import com.jetbrains.python.sdk.hatch.createSdk
import com.jetbrains.python.sdk.configuration.PyProjectSdkConfigurationExtension
import com.jetbrains.python.sdk.hatch.createSdk
class PyHatchSdkConfiguration : PyProjectSdkConfigurationExtension {
internal class PyHatchSdkConfiguration : PyProjectSdkConfigurationExtension {
companion object {
private val LOGGER = Logger.getInstance(PyHatchSdkConfiguration::class.java)
}
@RequiresBackgroundThread
override fun getIntention(module: Module): @IntentionName String? {
val isReadyAndHaveOwnership = runWithModalProgressBlocking(module.project, "Hatch Project Analysis") {
val isReadyAndHaveOwnership = runWithModalProgressBlocking(
module.project,
PyCharmCommunityCustomizationBundle.message("sdk.set.up.hatch.project.analysis")
) {
val hatchService = module.getHatchService().getOr { return@runWithModalProgressBlocking false }
hatchService.isHatchManagedProject().getOrNull() == true
}
@@ -112,6 +112,10 @@ const val ENV_TYPE_VIRTUAL: String = "virtual"
* Manage project environments
*/
class HatchEnv(runtime: HatchRuntime) : HatchCommand("env", runtime) {
companion object {
private val SHOW_RESPONSE_REGEX = """^\s+Standalone\s*\n((?:[+|].*[+|]\n)+)(?:\s+Matrices\s*\n((?:[+|].*[+|]\n)+))?$""".toRegex()
}
enum class CreateResult {
Created,
AlreadyExists,
@@ -228,9 +232,7 @@ class HatchEnv(runtime: HatchRuntime) : HatchCommand("env", runtime) {
suspend fun show(vararg envs: String, internal: Boolean = false): Result<HatchEnvironments, ExecException> {
val options = listOf(internal to "--internal").makeOptions()
val expectedOutput = """^\s+Standalone\s*\n((?:[+|].*[+|]\n)+)(?:\s+Matrices\s*\n((?:[+|].*[+|]\n)+))?$""".toRegex()
return executeAndMatch("show", "--ascii", *options, *envs, expectedOutput = expectedOutput) { matchResult ->
return executeAndMatch("show", "--ascii", *options, *envs, expectedOutput = SHOW_RESPONSE_REGEX) { matchResult ->
val (standaloneTable, matricesTable) = matchResult.destructured
val standalone = standaloneTable.parseAsciiTable()?.parseHatchEnvironments()?.map { it.first } ?: emptyList()
val matrices = matricesTable.parseAsciiTable()?.parseHatchEnvironments()?.mapNotNull {
@@ -42,20 +42,32 @@ class FileSystemOperationHatchError(eelFsError: EelFsError) : HatchError(
data class HatchVirtualEnvironment(
val hatchEnvironment: HatchEnvironment,
val pythonVirtualEnvironment: PythonVirtualEnvironment,
val pythonVirtualEnvironment: PythonVirtualEnvironment?,
) {
companion object {
val AVAILABLE_ENVIRONMENTS_FOR_NEW_PROJECT: List<HatchVirtualEnvironment> = listOf(
HatchVirtualEnvironment(HatchEnvironment.DEFAULT, PythonVirtualEnvironment.NotExisting())
HatchVirtualEnvironment(HatchEnvironment.DEFAULT, null)
)
}
}
/**
* Represents a Python virtual environment that can be either existing or non-existing.
*/
sealed interface PythonVirtualEnvironment {
val pythonHomePath: PythonHomePath?
val pythonHomePath: PythonHomePath
/**
* Represents an existing Python virtual environment.
* The environment was verified and the Python version was already discovered.
*/
data class Existing(override val pythonHomePath: PythonHomePath, val pythonVersion: String) : PythonVirtualEnvironment
data class NotExisting(override val pythonHomePath: PythonHomePath? = null) : PythonVirtualEnvironment
/**
* Represents a non-existing Python virtual environment.
* This class is used for cases where the Python virtual environment is expected or referenced but does not exist on the file system.
*/
data class NotExisting(override val pythonHomePath: PythonHomePath) : PythonVirtualEnvironment
}
data class ProjectStructure(
@@ -76,12 +76,13 @@ private class HatchEnvComboBoxListCellRenderer : ColoredListCellRenderer<HatchVi
}
icon = when (value.pythonVirtualEnvironment) {
null -> AllIcons.Nodes.Folder
is PythonVirtualEnvironment.Existing -> PythonIcons.Python.PythonClosed
is PythonVirtualEnvironment.NotExisting -> AllIcons.Nodes.Folder
}
append(value.hatchEnvironment.name, SimpleTextAttributes.REGULAR_ATTRIBUTES)
value.pythonVirtualEnvironment.pythonHomePath?.let { pythonHomePath ->
value.pythonVirtualEnvironment?.pythonHomePath?.let { pythonHomePath ->
append("\t", SimpleTextAttributes.REGULAR_ATTRIBUTES)
append(pythonHomePath.toString(), SimpleTextAttributes.GRAYED_SMALL_ATTRIBUTES)
}
@@ -14,6 +14,7 @@ object HatchSdkFlavor : CPythonSdkFlavor<HatchSdkFlavorData>() {
override fun getIcon(): Icon = PythonHatchIcons.Logo
override fun getFlavorDataClass(): Class<HatchSdkFlavorData> = HatchSdkFlavorData::class.java
override fun isValidSdkPath(pathStr: String): Boolean = false
override fun isPlatformIndependent(): Boolean = true
}
class HatchSdkFlavorProvider : PythonFlavorProvider {