mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-04-19 13:02:30 +07:00
cleanup [python]: Stop using deprecated API basePath and rootManager
GitOrigin-RevId: 1687601dcc175ccf34e71de2bb0585ebc0fa2740
This commit is contained in:
committed by
intellij-monorepo-bot
parent
98320dd3d0
commit
da3979b491
@@ -33,7 +33,7 @@ import com.jetbrains.python.pathValidation.ValidationRequest
|
||||
import com.jetbrains.python.pathValidation.validateExecutableFile
|
||||
import com.jetbrains.python.run.PythonInterpreterTargetEnvironmentFactory
|
||||
import com.jetbrains.python.sdk.PythonSdkUpdater
|
||||
import com.jetbrains.python.sdk.basePath
|
||||
import com.jetbrains.python.sdk.baseDir
|
||||
import com.jetbrains.python.sdk.conda.PyCondaSdkCustomizer
|
||||
import com.jetbrains.python.sdk.conda.createCondaSdkAlongWithNewEnv
|
||||
import com.jetbrains.python.sdk.conda.createCondaSdkFromExistingEnv
|
||||
@@ -63,9 +63,10 @@ internal class PyEnvironmentYmlSdkConfiguration : PyProjectSdkConfigurationExten
|
||||
|
||||
override val toolId: ToolId = CONDA_TOOL_ID
|
||||
|
||||
override suspend fun checkEnvironmentAndPrepareSdkCreator(module: Module, venvsInModule: List<PythonBinary>): CreateSdkInfo? = prepareSdkCreator(
|
||||
{ checkManageableEnv(module, it) }
|
||||
) { envExists -> { createAndAddSdk(module, envExists) } }
|
||||
override suspend fun checkEnvironmentAndPrepareSdkCreator(module: Module, venvsInModule: List<PythonBinary>): CreateSdkInfo? =
|
||||
prepareSdkCreator(
|
||||
{ checkManageableEnv(module, it) }
|
||||
) { envExists -> { createAndAddSdk(module, envExists) } }
|
||||
|
||||
override fun asPyProjectTomlSdkConfigurationExtension(): PyProjectTomlConfigurationExtension? = null
|
||||
|
||||
@@ -127,7 +128,7 @@ internal class PyEnvironmentYmlSdkConfiguration : PyProjectSdkConfigurationExten
|
||||
}.getOr { return it }
|
||||
|
||||
val shared = PyCondaSdkCustomizer.instance.sharedEnvironmentsByDefault
|
||||
val basePath = module.basePath
|
||||
val basePath = module.baseDir?.path
|
||||
|
||||
withContext(Dispatchers.EDT) {
|
||||
this@PyEnvironmentYmlSdkConfiguration.thisLogger()
|
||||
@@ -165,7 +166,7 @@ internal class PyEnvironmentYmlSdkConfiguration : PyProjectSdkConfigurationExten
|
||||
is PyCondaEnvIdentity.NamedEnv -> envIdentity.envName == envName
|
||||
is PyCondaEnvIdentity.UnnamedEnv -> if (shouldGuessEnvPrefix) {
|
||||
val envPath = Path.of(envIdentity.envPath)
|
||||
val sameModule = module.basePath?.toNioPathOrNull() == envPath.parent
|
||||
val sameModule = module.baseDir?.path?.toNioPathOrNull() == envPath.parent
|
||||
!envIdentity.isBase && sameModule && module.findAmongRoots(FileName(Path.of(envIdentity.envPath).name)) != null
|
||||
}
|
||||
else envIdentity.envPath == envPrefix
|
||||
|
||||
@@ -20,7 +20,7 @@ import com.jetbrains.python.PyBundle
|
||||
import com.jetbrains.python.PythonBinary
|
||||
import com.jetbrains.python.errorProcessing.PyResult
|
||||
import com.jetbrains.python.sdk.PythonSdkType
|
||||
import com.jetbrains.python.sdk.basePath
|
||||
import com.jetbrains.python.sdk.baseDir
|
||||
import com.jetbrains.python.sdk.configuration.*
|
||||
import com.jetbrains.python.sdk.findAmongRoots
|
||||
import com.jetbrains.python.sdk.impl.PySdkBundle
|
||||
@@ -42,9 +42,10 @@ internal class PyPipfileSdkConfiguration : PyProjectSdkConfigurationExtension {
|
||||
|
||||
override val toolId: ToolId = PIPENV_TOOL_ID
|
||||
|
||||
override suspend fun checkEnvironmentAndPrepareSdkCreator(module: Module, venvsInModule: List<PythonBinary>): CreateSdkInfo? = prepareSdkCreator(
|
||||
{ checkManageableEnv(module, it) }
|
||||
) { { createAndAddSdk(module) } }
|
||||
override suspend fun checkEnvironmentAndPrepareSdkCreator(module: Module, venvsInModule: List<PythonBinary>): CreateSdkInfo? =
|
||||
prepareSdkCreator(
|
||||
{ checkManageableEnv(module, it) }
|
||||
) { { createAndAddSdk(module) } }
|
||||
|
||||
override fun asPyProjectTomlSdkConfigurationExtension(): PyProjectTomlConfigurationExtension? = null
|
||||
|
||||
@@ -61,7 +62,7 @@ internal class PyPipfileSdkConfiguration : PyProjectSdkConfigurationExtension {
|
||||
canManage && checkExistence -> {
|
||||
PropertiesComponent.getInstance().pipenvPath = pipEnvExecutable.pathString
|
||||
val envPath = runPipEnv(
|
||||
module.basePath?.toNioPathOrNull(),
|
||||
module.baseDir?.path?.toNioPathOrNull(),
|
||||
"--venv",
|
||||
transformer = ZeroCodeStdoutParserTransformer { PyResult.success(Path.of(it)) }
|
||||
).successOrNull
|
||||
@@ -82,9 +83,9 @@ internal class PyPipfileSdkConfiguration : PyProjectSdkConfigurationExtension {
|
||||
private suspend fun createAndAddSdk(module: Module): PyResult<Sdk> {
|
||||
LOGGER.debug("Creating pipenv environment")
|
||||
return withBackgroundProgress(module.project, PyBundle.message("python.sdk.using.pipenv.sentence")) {
|
||||
val basePath = module.basePath
|
||||
val basePath = module.baseDir?.path
|
||||
?: return@withBackgroundProgress PyResult.localizedError(PyBundle.message("python.sdk.provided.path.is.invalid",
|
||||
module.basePath))
|
||||
module.baseDir?.path))
|
||||
val pipEnv = setupPipEnv(Path.of(basePath), null, true).getOr {
|
||||
PySdkConfigurationCollector.logPipEnv(module.project, PipEnvResult.CREATION_FAILURE)
|
||||
return@withBackgroundProgress it
|
||||
|
||||
@@ -21,7 +21,7 @@ import com.jetbrains.python.errorProcessing.PyResult
|
||||
import com.jetbrains.python.poetry.findPoetryLock
|
||||
import com.jetbrains.python.poetry.getPyProjectTomlForPoetry
|
||||
import com.jetbrains.python.sdk.PythonSdkType
|
||||
import com.jetbrains.python.sdk.basePath
|
||||
import com.jetbrains.python.sdk.baseDir
|
||||
import com.jetbrains.python.sdk.configuration.*
|
||||
import com.jetbrains.python.sdk.impl.PySdkBundle
|
||||
import com.jetbrains.python.sdk.impl.resolvePythonBinary
|
||||
@@ -47,9 +47,10 @@ internal class PyPoetrySdkConfiguration : PyProjectTomlConfigurationExtension {
|
||||
{ checkExistence -> checkManageableEnv(module, checkExistence, true) },
|
||||
) { { createPoetry(module) } }
|
||||
|
||||
override suspend fun createSdkWithoutPyProjectTomlChecks(module: Module, venvsInModule: List<PythonBinary>): CreateSdkInfo? = prepareSdkCreator(
|
||||
{ checkExistence -> checkManageableEnv(module, checkExistence, false) },
|
||||
) { { createPoetry(module) } }
|
||||
override suspend fun createSdkWithoutPyProjectTomlChecks(module: Module, venvsInModule: List<PythonBinary>): CreateSdkInfo? =
|
||||
prepareSdkCreator(
|
||||
{ checkExistence -> checkManageableEnv(module, checkExistence, false) },
|
||||
) { { createPoetry(module) } }
|
||||
|
||||
override fun asPyProjectTomlSdkConfigurationExtension(): PyProjectTomlConfigurationExtension = this
|
||||
|
||||
@@ -71,7 +72,7 @@ internal class PyPoetrySdkConfiguration : PyProjectTomlConfigurationExtension {
|
||||
|
||||
when {
|
||||
canManage && checkExistence -> {
|
||||
val basePath = module.basePath?.toNioPathOrNull()
|
||||
val basePath = module.baseDir?.path?.toNioPathOrNull()
|
||||
runPoetry(basePath, "check", "--lock").getOr { return@reportRawProgress envNotFound }
|
||||
val envPath = runPoetry(basePath, "env", "info", "-p")
|
||||
.mapSuccess { it.toNioPathOrNull() }
|
||||
@@ -87,9 +88,9 @@ internal class PyPoetrySdkConfiguration : PyProjectTomlConfigurationExtension {
|
||||
withBackgroundProgress(module.project, PyCharmCommunityCustomizationBundle.message("sdk.progress.text.setting.up.poetry.environment")) {
|
||||
LOGGER.debug("Creating poetry environment")
|
||||
|
||||
val basePath = module.basePath?.let { Path.of(it) }
|
||||
val basePath = module.baseDir?.path?.let { Path.of(it) }
|
||||
if (basePath == null) {
|
||||
return@withBackgroundProgress PyResult.localizedError(PyBundle.message("python.sdk.provided.path.is.invalid", module.basePath))
|
||||
return@withBackgroundProgress PyResult.localizedError(PyBundle.message("python.sdk.provided.path.is.invalid", module.baseDir?.path))
|
||||
}
|
||||
val tomlFile = PyProjectToml.findFile(module)
|
||||
val poetry = setupPoetry(basePath, null, true, tomlFile == null).getOr { return@withBackgroundProgress it }
|
||||
@@ -104,7 +105,7 @@ internal class PyPoetrySdkConfiguration : PyProjectTomlConfigurationExtension {
|
||||
PythonSdkUtil.getAllSdks().toTypedArray(),
|
||||
file,
|
||||
PythonSdkType.getInstance(),
|
||||
PyPoetrySdkAdditionalData(module.basePath?.let { Path.of(it) }),
|
||||
PyPoetrySdkAdditionalData(module.baseDir?.path?.let { Path.of(it) }),
|
||||
suggestedSdkName(basePath)
|
||||
)
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@ import com.intellij.python.pyproject.model.api.suggestSdk
|
||||
import com.jetbrains.python.PythonBinary
|
||||
import com.jetbrains.python.errorProcessing.PyResult
|
||||
import com.jetbrains.python.onSuccess
|
||||
import com.jetbrains.python.sdk.basePath
|
||||
import com.jetbrains.python.sdk.baseDir
|
||||
import com.jetbrains.python.sdk.configuration.*
|
||||
import com.jetbrains.python.sdk.persist
|
||||
import com.jetbrains.python.sdk.pyvenvContains
|
||||
@@ -81,7 +81,7 @@ internal class PyUvSdkConfiguration : PyProjectTomlConfigurationExtension {
|
||||
|
||||
private suspend fun createUv(module: Module, venvsInModule: List<PythonBinary>, envExists: Boolean): PyResult<Sdk> {
|
||||
val sdkAssociatedModule = module.getSdkAssociatedModule()
|
||||
val workingDir: Path? = tryResolvePath(sdkAssociatedModule.basePath)
|
||||
val workingDir: Path? = tryResolvePath(sdkAssociatedModule.baseDir?.path)
|
||||
if (workingDir == null) {
|
||||
throw IllegalStateException("Can't determine working dir for the module")
|
||||
}
|
||||
|
||||
@@ -28,9 +28,10 @@ import kotlin.io.path.name
|
||||
internal class PyVenvSdkConfiguration : PyProjectSdkConfigurationExtension {
|
||||
override val toolId: ToolId = VENV_TOOL_ID
|
||||
|
||||
override suspend fun checkEnvironmentAndPrepareSdkCreator(module: Module, venvsInModule: List<PythonBinary>): CreateSdkInfo? = prepareSdkCreator(
|
||||
{ checkManageableEnv(module, venvsInModule) }
|
||||
) { envExists -> { setupVenv(module, venvsInModule, envExists) } }
|
||||
override suspend fun checkEnvironmentAndPrepareSdkCreator(module: Module, venvsInModule: List<PythonBinary>): CreateSdkInfo? =
|
||||
prepareSdkCreator(
|
||||
{ checkManageableEnv(module, venvsInModule) }
|
||||
) { envExists -> { setupVenv(module, venvsInModule, envExists) } }
|
||||
|
||||
override fun asPyProjectTomlSdkConfigurationExtension(): PyProjectTomlConfigurationExtension? = null
|
||||
|
||||
@@ -65,7 +66,7 @@ internal class PyVenvSdkConfiguration : PyProjectSdkConfigurationExtension {
|
||||
val pyDetectedSdk = PyDetectedSdk(pythonBinary.toString())
|
||||
val sdk = pyDetectedSdk.setupAssociated(
|
||||
PythonSdkUtil.getAllSdks(),
|
||||
module.basePath,
|
||||
module.baseDir?.path,
|
||||
true,
|
||||
PyFlavorAndData(PyFlavorData.Empty, VirtualEnvSdkFlavor.getInstance())
|
||||
).getOr { return it }
|
||||
|
||||
@@ -13,7 +13,7 @@ import com.jetbrains.python.PythonInfo
|
||||
import com.jetbrains.python.Result
|
||||
import com.jetbrains.python.errorProcessing.MessageError
|
||||
import com.jetbrains.python.errorProcessing.PyResult
|
||||
import com.jetbrains.python.sdk.basePath
|
||||
import com.jetbrains.python.sdk.baseDir
|
||||
import java.nio.file.Path
|
||||
|
||||
const val HATCH_TOML: String = "hatch.toml"
|
||||
@@ -93,7 +93,10 @@ interface HatchService {
|
||||
* param[basePythonBinaryPath] base python for environment, the one on the PATH should be used if null.
|
||||
* param[envName] environment name to create, 'default' should be used if null.
|
||||
*/
|
||||
suspend fun createVirtualEnvironment(basePythonBinaryPath: PythonBinary? = null, envName: String? = null): PyResult<PythonVirtualEnvironment.Existing>
|
||||
suspend fun createVirtualEnvironment(
|
||||
basePythonBinaryPath: PythonBinary? = null,
|
||||
envName: String? = null,
|
||||
): PyResult<PythonVirtualEnvironment.Existing>
|
||||
|
||||
suspend fun findVirtualEnvironments(): PyResult<List<HatchVirtualEnvironment>>
|
||||
|
||||
@@ -108,7 +111,9 @@ interface HatchService {
|
||||
* Hatch Service for working directory (where hatch.toml / pyproject.toml is usually placed)
|
||||
*/
|
||||
suspend fun Path?.getHatchService(hatchExecutablePath: Path? = null, hatchEnvironmentName: String? = null): PyResult<HatchService> {
|
||||
return CliBasedHatchService(hatchExecutablePath = hatchExecutablePath, workingDirectoryPath = this, hatchEnvironmentName = hatchEnvironmentName)
|
||||
return CliBasedHatchService(hatchExecutablePath = hatchExecutablePath,
|
||||
workingDirectoryPath = this,
|
||||
hatchEnvironmentName = hatchEnvironmentName)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -126,7 +131,7 @@ suspend fun Module.getHatchService(hatchExecutablePath: Path? = null): PyResult<
|
||||
fun PythonHomePath.getHatchEnvVirtualProjectPath(): Path = this.parent.parent
|
||||
|
||||
fun resolveHatchWorkingDirectory(project: Project, module: Module?): PyResult<Path> {
|
||||
val pathString = module?.basePath ?: project.basePath
|
||||
val pathString = module?.baseDir?.path ?: project.basePath
|
||||
|
||||
return when (val path = pathString?.let { Path.of(it) }) {
|
||||
null -> Result.failure(WorkingDirectoryNotFoundHatchError(pathString))
|
||||
|
||||
@@ -6,12 +6,12 @@ import com.intellij.openapi.module.Module
|
||||
import com.intellij.openapi.util.io.NioFiles
|
||||
import com.intellij.util.system.OS
|
||||
import com.jetbrains.python.sdk.PySdkUtil
|
||||
import com.jetbrains.python.sdk.basePath
|
||||
import com.jetbrains.python.sdk.baseDir
|
||||
import java.nio.file.Path
|
||||
|
||||
|
||||
fun Module?.executeInModuleDir(executable: String, vararg arguments: String): ProcessOutput {
|
||||
val pyProjectPath = this?.basePath
|
||||
val pyProjectPath = this?.baseDir?.path
|
||||
val commandLine = GeneralCommandLine(executable, *arguments)
|
||||
return PySdkUtil.getProcessOutput(commandLine, pyProjectPath, emptyMap(), 5_000)
|
||||
}
|
||||
|
||||
@@ -12,19 +12,18 @@ import com.intellij.python.sdk.ui.evolution.ui.components.EvoTreeLeafElement
|
||||
import com.intellij.python.sdk.ui.evolution.ui.components.EvoTreeSection
|
||||
import com.intellij.python.sdk.ui.icons.PythonSdkUIIcons
|
||||
import com.jetbrains.python.Result
|
||||
import com.jetbrains.python.sdk.basePath
|
||||
import com.jetbrains.python.sdk.baseDir
|
||||
import com.jetbrains.python.venvReader.VirtualEnvReader
|
||||
import java.nio.file.Path
|
||||
import kotlin.collections.plus
|
||||
|
||||
internal class VenvSelectSdkProvider() : EvoSelectSdkProvider {
|
||||
internal class VenvSelectSdkProvider : EvoSelectSdkProvider {
|
||||
override fun getTreeElement(evoModuleSdk: EvoModuleSdk) = EvoTreeLazyNodeElement("pip", PythonSdkUIIcons.Tools.Pip) {
|
||||
val environments = VenvEvoSdkManager.findEnvironments(evoModuleSdk.module).getOr {
|
||||
return@EvoTreeLazyNodeElement it
|
||||
}
|
||||
val envByFolders = environments.groupBy { it.pythonBinaryPath?.parent?.parent?.parent }.toMutableMap()
|
||||
envByFolders.putIfAbsent(
|
||||
evoModuleSdk.module.basePath?.let { Path.of(it) },
|
||||
evoModuleSdk.module.baseDir?.path?.let { Path.of(it) },
|
||||
listOf(EvoSdk(icon = PythonSdkUIIcons.Tools.Pip, name = VirtualEnvReader.DEFAULT_VIRTUALENV_DIRNAME, pythonBinaryPath = null))
|
||||
)
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@ import java.nio.file.Path
|
||||
|
||||
@get:Deprecated("Use root manager directly and obey its contract",
|
||||
replaceWith = ReplaceWith(" ModuleRootManager.getInstance(this)"),
|
||||
level = DeprecationLevel.WARNING)
|
||||
level = DeprecationLevel.ERROR)
|
||||
val Module.rootManager: ModuleRootManager
|
||||
get() = ModuleRootManager.getInstance(this)
|
||||
|
||||
@@ -33,7 +33,7 @@ val Module.baseDir: VirtualFile?
|
||||
}
|
||||
|
||||
|
||||
@get:Deprecated("Representing path as string is discouraged", replaceWith = ReplaceWith("baseBase?.path"), level = DeprecationLevel.WARNING)
|
||||
@get:Deprecated("Representing path as string is discouraged", replaceWith = ReplaceWith("baseBase?.path"), level = DeprecationLevel.ERROR)
|
||||
val Module.basePath: String?
|
||||
get() = baseDir?.path
|
||||
|
||||
|
||||
@@ -200,7 +200,7 @@ object SdksKeeper {
|
||||
fun Sdk.setAssociationToModuleAsync(module: Module) {
|
||||
requirePythonSdk()
|
||||
|
||||
val path = module.basePath
|
||||
val path = module.baseDir?.path
|
||||
assert(path != null) { "Module $module has not paths, and can't be associated" }
|
||||
|
||||
val data = getOrCreateAdditionalData()
|
||||
@@ -222,7 +222,7 @@ fun Sdk.setAssociationToModuleAsync(module: Module) {
|
||||
suspend fun Sdk.setAssociationToModule(module: Module) {
|
||||
requirePythonSdk()
|
||||
|
||||
val path = module.basePath
|
||||
val path = module.baseDir?.path
|
||||
assert(path != null) { "Module $module has not paths, and can't be associated" }
|
||||
setAssociationToPath(path)
|
||||
}
|
||||
|
||||
@@ -6,13 +6,13 @@ import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.projectRoots.SdkModificator
|
||||
import com.intellij.util.concurrency.ThreadingAssertions
|
||||
import com.jetbrains.python.sdk.PythonSdkAdditionalData
|
||||
import com.jetbrains.python.sdk.basePath
|
||||
import com.jetbrains.python.sdk.baseDir
|
||||
import com.jetbrains.python.sdk.flavors.PythonSdkFlavor
|
||||
import org.jetbrains.annotations.ApiStatus
|
||||
|
||||
@ApiStatus.Internal
|
||||
fun SdkModificator.associateWithModule(module: Module) {
|
||||
val basePath = module.basePath ?: throw IllegalArgumentException("Module $module has no roots and can't be associated")
|
||||
val basePath = module.baseDir?.path ?: throw IllegalArgumentException("Module $module has no roots and can't be associated")
|
||||
getOrCreateSdkAdditionalData().associatedModulePath = basePath
|
||||
}
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@ import com.intellij.openapi.module.ModuleManager
|
||||
import com.intellij.openapi.module.ModuleUtilCore
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.projectRoots.Sdk
|
||||
import com.intellij.openapi.roots.ModuleRootManager
|
||||
import com.intellij.openapi.util.Pair
|
||||
import com.intellij.openapi.vfs.VirtualFile
|
||||
import com.intellij.psi.PsiElement
|
||||
@@ -274,7 +275,7 @@ fun getModuleToStartConsole(project: Project, moduleManager: ModuleManager): Mod
|
||||
}
|
||||
|
||||
val projectLocalModule = moduleManager.modules.firstOrNull {
|
||||
val roots = it.rootManager.contentRoots
|
||||
val roots = ModuleRootManager.getInstance(it).contentRoots
|
||||
roots.all { it.isInLocalFileSystem }
|
||||
}
|
||||
if (projectLocalModule != null) {
|
||||
|
||||
@@ -9,6 +9,7 @@ import com.intellij.openapi.module.Module
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.project.modules
|
||||
import com.intellij.openapi.projectRoots.Sdk
|
||||
import com.intellij.openapi.roots.ModuleRootManager
|
||||
import com.intellij.openapi.vfs.VirtualFile
|
||||
import com.intellij.openapi.vfs.VirtualFileManager
|
||||
import com.intellij.openapi.vfs.findOrCreateFile
|
||||
@@ -102,7 +103,7 @@ object PythonRequirementTxtSdkUtils {
|
||||
*/
|
||||
@JvmStatic
|
||||
fun detectRequirementsTxtInModule(module: Module): VirtualFile? {
|
||||
val requirementsPath = module.rootManager.contentRoots.firstNotNullOfOrNull {
|
||||
val requirementsPath = ModuleRootManager.getInstance(module).contentRoots.firstNotNullOfOrNull {
|
||||
it.findChild(PythonSdkAdditionalData.REQUIREMENT_TXT_DEFAULT)
|
||||
}
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ package com.jetbrains.python.packaging.setupPy
|
||||
import com.intellij.openapi.application.runReadAction
|
||||
import com.intellij.openapi.command.WriteCommandAction
|
||||
import com.intellij.openapi.module.Module
|
||||
import com.intellij.openapi.roots.ModuleRootManager
|
||||
import com.intellij.openapi.util.Ref
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.PsiManager
|
||||
@@ -28,7 +29,7 @@ internal object SetupPyHelpers {
|
||||
|
||||
@JvmStatic
|
||||
fun detectSetupPyInModule(module: Module): PyFile? {
|
||||
val file = module.rootManager.contentRoots.firstNotNullOfOrNull {
|
||||
val file = ModuleRootManager.getInstance(module).contentRoots.firstNotNullOfOrNull {
|
||||
it.findChild(SETUP_PY)
|
||||
} ?: return null
|
||||
|
||||
|
||||
@@ -85,7 +85,7 @@ suspend fun createVenvAndSdk(
|
||||
}
|
||||
|
||||
logger.info("using venv python $venvPython")
|
||||
val sdkBasePath = moduleOrProject.moduleIfExists?.basePath ?: project.basePath
|
||||
val sdkBasePath = moduleOrProject.moduleIfExists?.baseDir?.path ?: project.basePath
|
||||
val sdk = getSdk(venvPython, sdkBasePath?.let { Path.of(it) })
|
||||
if (moduleOrProject.moduleIfExists == null && project.modules.isEmpty()) {
|
||||
writeAction {
|
||||
|
||||
@@ -101,7 +101,7 @@ fun filterSystemWideSdks(existingSdks: List<Sdk>): List<Sdk> {
|
||||
@Internal
|
||||
fun configurePythonSdk(project: Project, module: Module, sdk: Sdk) {
|
||||
// in case module contains root of the project we consider it as a project wide interpreter
|
||||
if (project.basePath == module.basePath) {
|
||||
if (project.basePath == module.baseDir?.path) {
|
||||
project.pythonSdk = sdk
|
||||
}
|
||||
|
||||
@@ -275,7 +275,7 @@ internal fun showSdkExecutionException(sdk: Sdk?, e: ExecutionException, @NlsCon
|
||||
|
||||
@Internal
|
||||
fun Sdk.isAssociatedWithModule(module: Module?): Boolean {
|
||||
val basePath = module?.basePath
|
||||
val basePath = module?.baseDir?.path
|
||||
val associatedPath = associatedModulePath
|
||||
if (basePath != null && associatedPath == basePath) return true
|
||||
if (isAssociatedWithAnotherModule(module)) return false
|
||||
@@ -284,7 +284,7 @@ fun Sdk.isAssociatedWithModule(module: Module?): Boolean {
|
||||
|
||||
@Internal
|
||||
fun Sdk.isAssociatedWithAnotherModule(module: Module?): Boolean {
|
||||
val basePath = module?.basePath ?: return false
|
||||
val basePath = module?.baseDir?.path ?: return false
|
||||
val associatedPath = associatedModulePath ?: return false
|
||||
return basePath != associatedPath
|
||||
}
|
||||
@@ -334,7 +334,7 @@ suspend fun PyDetectedSdk.setupSdk(
|
||||
existingSdks: List<Sdk>,
|
||||
doAssociate: Boolean,
|
||||
) {
|
||||
val newSdk = setupAssociated(existingSdks, module.basePath, doAssociate).getOr {
|
||||
val newSdk = setupAssociated(existingSdks, module.baseDir?.path, doAssociate).getOr {
|
||||
ShowingMessageErrorSync.emit(it.error, module.project)
|
||||
return
|
||||
}
|
||||
@@ -623,6 +623,7 @@ val Sdk.sdkSeemsValid: Boolean
|
||||
fun setPythonSdk(module: Module, sdk: Sdk) {
|
||||
module.pythonSdk = sdk
|
||||
}
|
||||
|
||||
@Internal
|
||||
@Deprecated("Use module.pythonSdk", replaceWith = ReplaceWith("module.pythonSdk"), level = DeprecationLevel.ERROR)
|
||||
fun getPythonSdk(module: Module): Sdk? = module.pythonSdk
|
||||
fun getPythonSdk(module: Module): Sdk? = module.pythonSdk
|
||||
@@ -69,7 +69,7 @@ internal abstract class CustomNewEnvironmentCreator<P : PathHolder>(
|
||||
is ModuleOrProject.ModuleAndProject -> moduleOrProject.module
|
||||
is ModuleOrProject.ProjectOnly -> null
|
||||
}
|
||||
val moduleBasePath = module?.basePath?.let { Path.of(it) }
|
||||
val moduleBasePath = module?.baseDir?.path?.let { Path.of(it) }
|
||||
?: model.projectPathFlows.projectPath.first()
|
||||
?: error("module base path can't be recognized, both module and project are nulls")
|
||||
|
||||
@@ -133,9 +133,10 @@ internal abstract class CustomNewEnvironmentCreator<P : PathHolder>(
|
||||
val installedSdk = when (baseInterpreter) {
|
||||
is InstallableSelectableInterpreter -> installBaseSdk(baseInterpreter.sdk, model.existingSdks)
|
||||
?.let {
|
||||
val sdkWrapper = runWithModalProgressBlocking(ModalTaskOwner.guess(), message("sdk.create.custom.venv.progress.title.detect.executable")) {
|
||||
model.fileSystem.wrapSdk(it)
|
||||
}
|
||||
val sdkWrapper =
|
||||
runWithModalProgressBlocking(ModalTaskOwner.guess(), message("sdk.create.custom.venv.progress.title.detect.executable")) {
|
||||
model.fileSystem.wrapSdk(it)
|
||||
}
|
||||
val installed = model.addInstalledInterpreter(sdkWrapper.homePath, baseInterpreter.pythonInfo)
|
||||
model.state.baseInterpreter.set(installed)
|
||||
installed
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
package com.jetbrains.python.sdk.add.v2
|
||||
|
||||
import com.intellij.openapi.projectRoots.Sdk
|
||||
import com.intellij.openapi.roots.ModuleRootManager
|
||||
import com.intellij.openapi.util.io.toNioPathOrNull
|
||||
import com.jetbrains.python.Result
|
||||
import com.jetbrains.python.errorProcessing.ErrorSink
|
||||
@@ -36,7 +37,7 @@ class PythonAddLocalInterpreterPresenter(
|
||||
*/
|
||||
val pathForVEnv: Path
|
||||
get() = when (moduleOrProject) {
|
||||
is ModuleOrProject.ModuleAndProject -> moduleOrProject.module.rootManager.contentRoots.firstOrNull()?.toNioPath()
|
||||
is ModuleOrProject.ModuleAndProject -> ModuleRootManager.getInstance(moduleOrProject.module).contentRoots.firstOrNull()?.toNioPath()
|
||||
?: moduleOrProject.project.basePath?.toNioPathOrNull()
|
||||
is ModuleOrProject.ProjectOnly -> moduleOrProject.project.basePath?.toNioPathOrNull()
|
||||
} ?: envReader.getVEnvRootDir()
|
||||
|
||||
@@ -27,7 +27,7 @@ import com.jetbrains.python.sdk.add.v2.pipenv.PipenvViewModel
|
||||
import com.jetbrains.python.sdk.add.v2.poetry.PoetryViewModel
|
||||
import com.jetbrains.python.sdk.add.v2.uv.UvViewModel
|
||||
import com.jetbrains.python.sdk.add.v2.venv.VenvViewModel
|
||||
import com.jetbrains.python.sdk.basePath
|
||||
import com.jetbrains.python.sdk.baseDir
|
||||
import com.jetbrains.python.target.ui.TargetPanelExtension
|
||||
import kotlinx.coroutines.*
|
||||
import kotlinx.coroutines.flow.*
|
||||
@@ -282,7 +282,7 @@ internal val <P : PathHolder> PythonAddInterpreterModel<P>.existingSdks: List<Sd
|
||||
internal suspend fun PythonAddInterpreterModel<*>.getBasePath(module: Module?): Path = withContext(Dispatchers.IO) {
|
||||
val pyProjectTomlBased = module?.let { PyProjectToml.findFile(it)?.toNioPathOrNull()?.parent }
|
||||
|
||||
pyProjectTomlBased ?: module?.basePath?.let { Path.of(it) } ?: projectPathFlows.projectPathWithDefault.first()
|
||||
pyProjectTomlBased ?: module?.baseDir?.path?.let { Path.of(it) } ?: projectPathFlows.projectPathWithDefault.first()
|
||||
}
|
||||
|
||||
private fun <T : MaybeSystemPython> Flow<Iterable<T>>.sysPythonsOnly(): Flow<List<T>> = map { it.sysPythonsOnly() }
|
||||
|
||||
@@ -25,7 +25,7 @@ import com.jetbrains.python.sdk.add.v2.PythonSupportedEnvironmentManagers.POETRY
|
||||
import com.jetbrains.python.sdk.add.v2.PythonSupportedEnvironmentManagers.PYTHON
|
||||
import com.jetbrains.python.sdk.add.v2.VenvExistenceValidationState.Error
|
||||
import com.jetbrains.python.sdk.add.v2.VenvExistenceValidationState.Invisible
|
||||
import com.jetbrains.python.sdk.basePath
|
||||
import com.jetbrains.python.sdk.baseDir
|
||||
import com.jetbrains.python.sdk.poetry.configurePoetryEnvironment
|
||||
import com.jetbrains.python.sdk.poetry.createNewPoetrySdk
|
||||
import com.jetbrains.python.statistics.InterpreterType
|
||||
@@ -141,7 +141,8 @@ internal class EnvironmentCreatorPoetry<P : PathHolder>(
|
||||
|
||||
@Service(Service.Level.APP)
|
||||
@State(name = "PyPoetrySettings", storages = [Storage("pyPoetrySettings.xml")])
|
||||
private class PoetryConfigService : SerializablePersistentStateComponent<PoetryConfigService.PyPoetrySettingsState>(PyPoetrySettingsState()) {
|
||||
private class PoetryConfigService :
|
||||
SerializablePersistentStateComponent<PoetryConfigService.PyPoetrySettingsState>(PyPoetrySettingsState()) {
|
||||
class PyPoetrySettingsState : BaseState() {
|
||||
var isInProjectEnv = false
|
||||
}
|
||||
@@ -150,7 +151,7 @@ private class PoetryConfigService : SerializablePersistentStateComponent<PoetryC
|
||||
val hasPoetryToml = findPoetryToml(module) != null
|
||||
if (state.isInProjectEnv || hasPoetryToml) {
|
||||
val modulePath = withContext(Dispatchers.IO) {
|
||||
PyProjectToml.findFile(module)?.parent?.toNioPath() ?: module.basePath?.let { Path.of(it) }
|
||||
PyProjectToml.findFile(module)?.parent?.toNioPath() ?: module.baseDir?.path?.let { Path.of(it) }
|
||||
}
|
||||
configurePoetryEnvironment(modulePath, "virtualenvs.in-project", state.isInProjectEnv.toString(), "--local")
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@ import com.jetbrains.python.Result
|
||||
import com.jetbrains.python.errorProcessing.PyResult
|
||||
import com.jetbrains.python.sdk.ModuleOrProject
|
||||
import com.jetbrains.python.sdk.add.v2.*
|
||||
import com.jetbrains.python.sdk.baseDir
|
||||
import com.jetbrains.python.sdk.basePath
|
||||
import com.jetbrains.python.sdk.legacy.PythonSdkUtil
|
||||
import com.jetbrains.python.sdk.moduleIfExists
|
||||
@@ -43,7 +44,7 @@ internal class PoetryExistingEnvironmentSelector<P : PathHolder>(model: PythonMu
|
||||
return Result.success(it)
|
||||
}
|
||||
|
||||
val basePathString = moduleOrProject.moduleIfExists?.basePath ?: moduleOrProject.project.basePath
|
||||
val basePathString = moduleOrProject.moduleIfExists?.baseDir?.path ?: moduleOrProject.project.basePath
|
||||
val basePath = basePathString?.let { Path.of(it) } ?: error("module base path is not valid: $basePathString")
|
||||
|
||||
return createPoetrySdk(basePath, pythonBinaryPath)
|
||||
|
||||
@@ -3,6 +3,7 @@ package com.jetbrains.python.sdk.add.v2
|
||||
|
||||
import com.intellij.openapi.diagnostic.fileLogger
|
||||
import com.intellij.openapi.module.Module
|
||||
import com.intellij.openapi.roots.ModuleRootManager
|
||||
import com.jetbrains.python.sdk.*
|
||||
import com.jetbrains.python.venvReader.VirtualEnvReader
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
@@ -73,7 +74,7 @@ suspend fun <P : PathHolder> sortForExistingEnvironment(
|
||||
if (module != null) {
|
||||
when (it.homePath) {
|
||||
is PathHolder.Eel -> {
|
||||
if (module.rootManager.contentRoots.any { root -> it.homePath.path.startsWith(root.toNioPath()) }) {
|
||||
if (ModuleRootManager.getInstance(module).contentRoots.any { root -> it.homePath.path.startsWith(root.toNioPath()) }) {
|
||||
return@groupBy Group.ASSOC_WITH_PROJ_ROOT
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@ import com.jetbrains.python.getOrNull
|
||||
import com.jetbrains.python.sdk.ModuleOrProject
|
||||
import com.jetbrains.python.sdk.add.v2.*
|
||||
import com.jetbrains.python.sdk.associatedModulePath
|
||||
import com.jetbrains.python.sdk.basePath
|
||||
import com.jetbrains.python.sdk.baseDir
|
||||
import com.jetbrains.python.sdk.impl.resolvePythonBinary
|
||||
import com.jetbrains.python.sdk.isAssociatedWithModule
|
||||
import com.jetbrains.python.sdk.legacy.PythonSdkUtil
|
||||
@@ -30,8 +30,8 @@ import kotlin.io.path.exists
|
||||
import kotlin.io.path.pathString
|
||||
|
||||
|
||||
internal class UvExistingEnvironmentSelector<P : PathHolder>(model: PythonMutableTargetAddInterpreterModel<P>, module: Module?)
|
||||
: CustomExistingEnvironmentSelector<P>("uv", model, module) {
|
||||
internal class UvExistingEnvironmentSelector<P : PathHolder>(model: PythonMutableTargetAddInterpreterModel<P>, module: Module?) :
|
||||
CustomExistingEnvironmentSelector<P>("uv", model, module) {
|
||||
override val interpreterType: InterpreterType = InterpreterType.UV
|
||||
override val toolState: ToolValidator<P> = model.uvViewModel.toolValidator
|
||||
override val toolExecutable: ObservableProperty<ValidatedPath.Executable<P>?> = model.uvViewModel.uvExecutable
|
||||
@@ -46,7 +46,7 @@ internal class UvExistingEnvironmentSelector<P : PathHolder>(model: PythonMutabl
|
||||
val allSdk = PythonSdkUtil.getAllSdks()
|
||||
val existingSdk = allSdk.find { it.homePath == selectedInterpreterPath.path.pathString }
|
||||
val associatedModule = extractModule(moduleOrProject)
|
||||
val basePathString = associatedModule?.basePath ?: moduleOrProject.project.basePath
|
||||
val basePathString = associatedModule?.baseDir?.path ?: moduleOrProject.project.basePath
|
||||
val projectDir = tryResolvePath(basePathString)
|
||||
?: return PyResult.localizedError(PyBundle.message("python.sdk.provided.path.is.invalid", basePathString))
|
||||
|
||||
|
||||
@@ -24,7 +24,6 @@ import com.intellij.platform.ide.progress.ModalTaskOwner
|
||||
import com.intellij.platform.ide.progress.runWithModalProgressBlocking
|
||||
import com.intellij.remote.RemoteSdkException
|
||||
import com.intellij.util.concurrency.annotations.RequiresEdt
|
||||
import com.jetbrains.python.sdk.impl.PySdkBundle
|
||||
import com.jetbrains.python.Result
|
||||
import com.jetbrains.python.packaging.PyPackageManagers
|
||||
import com.jetbrains.python.packaging.PyTargetEnvCreationManager
|
||||
@@ -33,6 +32,7 @@ import com.jetbrains.python.sdk.*
|
||||
import com.jetbrains.python.sdk.flavors.PyFlavorAndData
|
||||
import com.jetbrains.python.sdk.flavors.PyFlavorData
|
||||
import com.jetbrains.python.sdk.flavors.VirtualEnvSdkFlavor
|
||||
import com.jetbrains.python.sdk.impl.PySdkBundle
|
||||
import com.jetbrains.python.target.PyTargetAwareAdditionalData
|
||||
import com.jetbrains.python.target.getInterpreterVersion
|
||||
import com.jetbrains.python.target.ui.TargetPanelExtension
|
||||
@@ -68,7 +68,7 @@ fun createVirtualEnvAndSdkSynchronously(
|
||||
baseSdk
|
||||
}
|
||||
|
||||
val projectPath = projectBasePath ?: module?.basePath ?: project?.basePath
|
||||
val projectPath = projectBasePath ?: module?.baseDir?.path ?: project?.basePath
|
||||
val task = object : Task.WithResult<String, ExecutionException>(project, PySdkBundle.message("python.creating.venv.title"), false) {
|
||||
override fun compute(indicator: ProgressIndicator): String {
|
||||
indicator.isIndeterminate = true
|
||||
|
||||
@@ -120,7 +120,7 @@ internal suspend fun detectPoetryEnvs(
|
||||
existingSdkPaths: Set<String>?,
|
||||
projectPath: @SystemIndependent @NonNls String?,
|
||||
): List<PyDetectedSdk> {
|
||||
val path = module?.basePath?.let { Path.of(it) } ?: projectPath?.let { Path.of(it) } ?: return emptyList()
|
||||
val path = module?.baseDir?.path?.let { Path.of(it) } ?: projectPath?.let { Path.of(it) } ?: return emptyList()
|
||||
return getPoetryEnvs(path).filter { existingSdkPaths?.contains(getPythonExecutable(it)) != false }
|
||||
.map { PyDetectedSdk(getPythonExecutable(it)) }
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ import com.jetbrains.python.psi.stubs.PyDecoratorStub
|
||||
import com.jetbrains.python.psi.stubs.PyDecoratorStubIndex
|
||||
import com.jetbrains.python.psi.stubs.PyTestFixtureDecoratorStub
|
||||
import com.jetbrains.python.psi.types.TypeEvalContext
|
||||
import com.jetbrains.python.sdk.basePath
|
||||
import com.jetbrains.python.sdk.baseDir
|
||||
import com.jetbrains.python.sdk.pythonSdk
|
||||
import com.jetbrains.python.testing.PyTestFactory
|
||||
import com.jetbrains.python.testing.TestRunnerService
|
||||
@@ -52,23 +52,27 @@ internal fun getFixtureLink(element: PyElement, typeEvalContext: TypeEvalContext
|
||||
/**
|
||||
* If named parameter or reference expression has fixture (and import statement) -- return it
|
||||
*/
|
||||
private fun getFixtureAsExpressionLink(element: PyParameterOrPyReferenceExpression,
|
||||
typeEvalContext: TypeEvalContext,
|
||||
module: Module): NamedFixtureLink? {
|
||||
private fun getFixtureAsExpressionLink(
|
||||
element: PyParameterOrPyReferenceExpression,
|
||||
typeEvalContext: TypeEvalContext,
|
||||
module: Module,
|
||||
): NamedFixtureLink? {
|
||||
val pyExpression = element.expression
|
||||
val func = PsiTreeUtil.getParentOfType(pyExpression, PyFunction::class.java) ?: return null
|
||||
val fixtureCandidates = getFixtures(module, func, typeEvalContext).filter { o -> o.name == pyExpression.name }
|
||||
return module.basePath?.let { return findRightFixture(fixtureCandidates, func, pyExpression, typeEvalContext, it) }
|
||||
return module.baseDir?.path?.let { return findRightFixture(fixtureCandidates, func, pyExpression, typeEvalContext, it) }
|
||||
}
|
||||
|
||||
/**
|
||||
* If string literal has fixture (and import statement) -- return it
|
||||
*/
|
||||
private fun getFixtureAsStringLink(element: PyStringLiteralExpression,
|
||||
typeEvalContext: TypeEvalContext,
|
||||
module: Module): NamedFixtureLink? {
|
||||
private fun getFixtureAsStringLink(
|
||||
element: PyStringLiteralExpression,
|
||||
typeEvalContext: TypeEvalContext,
|
||||
module: Module,
|
||||
): NamedFixtureLink? {
|
||||
val fixtureCandidates = getModuleFixtures(module).filter { o -> o.name == element.stringValue }
|
||||
return module.basePath?.let { return findRightFixture(fixtureCandidates, null, element, typeEvalContext, it) }
|
||||
return module.baseDir?.path?.let { return findRightFixture(fixtureCandidates, null, element, typeEvalContext, it) }
|
||||
}
|
||||
|
||||
data class NamedFixtureLink(val fixture: PyTestFixture, val importElement: PyElement?)
|
||||
@@ -98,11 +102,13 @@ private fun PyTestFixture.isInConftestInDir(directory: PsiDirectory): Boolean {
|
||||
*
|
||||
* @return Fixture and import element if fixture was imported or null
|
||||
*/
|
||||
private fun findRightFixture(fixtureCandidates: List<PyTestFixture>,
|
||||
func: PyFunction?,
|
||||
pyFixtureElement: PyElement,
|
||||
typeEvalContext: TypeEvalContext,
|
||||
projectPath: String): NamedFixtureLink? {
|
||||
private fun findRightFixture(
|
||||
fixtureCandidates: List<PyTestFixture>,
|
||||
func: PyFunction?,
|
||||
pyFixtureElement: PyElement,
|
||||
typeEvalContext: TypeEvalContext,
|
||||
projectPath: String,
|
||||
): NamedFixtureLink? {
|
||||
val elementName = pyFixtureElement.getFixtureName() ?: return null
|
||||
|
||||
// request fixture
|
||||
@@ -167,10 +173,12 @@ private fun findRightFixture(fixtureCandidates: List<PyTestFixture>,
|
||||
/**
|
||||
* Search fixture or imported fixture in 'constest.py' file
|
||||
*/
|
||||
private fun searchInConftest(fixtureCandidates: List<PyTestFixture>,
|
||||
currentDirectory: PsiDirectory,
|
||||
elementName: String,
|
||||
func: PyFunction?): NamedFixtureLink? {
|
||||
private fun searchInConftest(
|
||||
fixtureCandidates: List<PyTestFixture>,
|
||||
currentDirectory: PsiDirectory,
|
||||
elementName: String,
|
||||
func: PyFunction?,
|
||||
): NamedFixtureLink? {
|
||||
fixtureCandidates.find { it.isInConftestInDir(currentDirectory) }?.let { return NamedFixtureLink(it, null) }
|
||||
|
||||
// search in imports and 'pytest_plugins' in "conftest.py" file
|
||||
@@ -184,10 +192,12 @@ private fun searchInConftest(fixtureCandidates: List<PyTestFixture>,
|
||||
/**
|
||||
* Return fixture from import statements
|
||||
*/
|
||||
private fun getFixtureFromImports(targetFile: PyFile,
|
||||
elementName: String,
|
||||
func: PyFunction?,
|
||||
fixtureCandidates: List<PyTestFixture>): NamedFixtureLink? {
|
||||
private fun getFixtureFromImports(
|
||||
targetFile: PyFile,
|
||||
elementName: String,
|
||||
func: PyFunction?,
|
||||
fixtureCandidates: List<PyTestFixture>,
|
||||
): NamedFixtureLink? {
|
||||
findImportedFixtureInFile(targetFile, elementName, func, fixtureCandidates)?.let { return it }
|
||||
findImportedFixtureWithWildcard(targetFile, elementName, func, fixtureCandidates)?.let { return it }
|
||||
return null
|
||||
@@ -199,16 +209,18 @@ private fun getFixtureFromImports(targetFile: PyFile,
|
||||
* `from module import some_fixture as sf` or
|
||||
* `import module.some_fixture`
|
||||
*/
|
||||
private fun findImportedFixtureInFile(targetFile: PyFile,
|
||||
elementName: String,
|
||||
func: PyFunction?,
|
||||
fixtureCandidates: List<PyTestFixture>): NamedFixtureLink? {
|
||||
private fun findImportedFixtureInFile(
|
||||
targetFile: PyFile,
|
||||
elementName: String,
|
||||
func: PyFunction?,
|
||||
fixtureCandidates: List<PyTestFixture>,
|
||||
): NamedFixtureLink? {
|
||||
val importedFixture = targetFile.findExportedName(elementName) as? PyImportElement
|
||||
val resolveImportElements = importedFixture?.multiResolve()?.map { it.element }
|
||||
if (importedFixture != null) {
|
||||
// if fixture is imported as `from module import some_fixture as sf`
|
||||
resolveImportElements?.firstOrNull { (it as? PyFunction)?.isFixture() == true }?.let { fixture ->
|
||||
return (fixture as? PyFunction)?.let { NamedFixtureLink(PyTestFixture(func, fixture, fixture.name ?: ""), importedFixture) }
|
||||
return (fixture as? PyFunction)?.let { NamedFixtureLink(PyTestFixture(func, fixture, fixture.name ?: ""), importedFixture) }
|
||||
}
|
||||
|
||||
resolveImportElements?.let { list ->
|
||||
@@ -225,26 +237,30 @@ private fun findImportedFixtureInFile(targetFile: PyFile,
|
||||
*
|
||||
* `from module import *`
|
||||
*/
|
||||
private fun findImportedFixtureWithWildcard(targetFile: PyFile,
|
||||
elementName: String,
|
||||
func: PyFunction?,
|
||||
fixtureCandidates: List<PyTestFixture>): NamedFixtureLink? {
|
||||
private fun findImportedFixtureWithWildcard(
|
||||
targetFile: PyFile,
|
||||
elementName: String,
|
||||
func: PyFunction?,
|
||||
fixtureCandidates: List<PyTestFixture>,
|
||||
): NamedFixtureLink? {
|
||||
val starImportElements = targetFile.importBlock.filter { importStatement -> importStatement.children.any { it is PyStarImportElement } }
|
||||
if (starImportElements.isNotEmpty()) {
|
||||
// Map: containing file to fixture
|
||||
val fileToFixture = fixtureCandidates.mapNotNull { candidate -> (candidate.getContainingFile() as? PyFile)?.let { it to candidate } }.toMap()
|
||||
val fileToFixture =
|
||||
fixtureCandidates.mapNotNull { candidate -> (candidate.getContainingFile() as? PyFile)?.let { it to candidate } }.toMap()
|
||||
// Map: resolved source file to PyStarImportElement (needs for import reference)
|
||||
val sourceToImport = starImportElements.mapNotNull { elem ->
|
||||
val sourceFile = elem.children.firstOrNull { it is PyReferenceExpression }?.let { it.reference?.resolve() as? PyFile }
|
||||
val starImportElement = elem.children.firstOrNull { it is PyStarImportElement } as? PyStarImportElement
|
||||
if (sourceFile == null || starImportElement == null) {
|
||||
null
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
Pair(sourceFile, starImportElement)
|
||||
}
|
||||
}
|
||||
|
||||
sourceToImport.forEach {( sourceFile, importElement) ->
|
||||
sourceToImport.forEach { (sourceFile, importElement) ->
|
||||
// if a source file is a required file
|
||||
fileToFixture[sourceFile]?.let { return NamedFixtureLink(it, importElement) }
|
||||
|
||||
@@ -258,6 +274,7 @@ private fun findImportedFixtureWithWildcard(targetFile: PyFile,
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
/**
|
||||
* Return fixture from pytest_plugins
|
||||
*/
|
||||
@@ -337,7 +354,7 @@ internal fun resolve(expr: PyExpression): PyExpression? {
|
||||
when (expr) {
|
||||
is PyStringLiteralExpression -> return expr
|
||||
is PyQualifiedExpression -> return getFixtureNameFromQualifiedName(expr)
|
||||
}
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
|
||||
@@ -8,15 +8,14 @@ import com.jetbrains.python.packaging.PyPackageName
|
||||
import com.jetbrains.python.packaging.common.PythonPackage
|
||||
import com.jetbrains.python.packaging.packageRequirements.PythonPackageRequirementExtractor
|
||||
import com.jetbrains.python.packaging.packageRequirements.PythonPackageRequiresExtractorProvider
|
||||
import com.jetbrains.python.sdk.basePath
|
||||
import com.jetbrains.python.sdk.baseDir
|
||||
import com.jetbrains.python.sdk.uv.UvSdkAdditionalData
|
||||
import com.jetbrains.python.sdk.uv.impl.createUvCli
|
||||
import com.jetbrains.python.sdk.uv.impl.createUvLowLevel
|
||||
import java.nio.file.Path
|
||||
|
||||
internal class UvPackageRequirementExtractor(private val uvWorkingDirectory: Path?) : PythonPackageRequirementExtractor {
|
||||
override suspend fun extract(pkg: PythonPackage, module: Module): List<PyPackageName> {
|
||||
val uvWorkingDirectory = uvWorkingDirectory ?: Path.of(module.basePath!!)
|
||||
val uvWorkingDirectory = uvWorkingDirectory ?: Path.of(module.baseDir?.path!!)
|
||||
val uv = createUvLowLevel(uvWorkingDirectory).getOr {
|
||||
thisLogger().info("cannot run uv: ${it.error}")
|
||||
return emptyList()
|
||||
@@ -28,7 +27,7 @@ internal class UvPackageRequirementExtractor(private val uvWorkingDirectory: Pat
|
||||
}
|
||||
}
|
||||
|
||||
internal class UvPackageRequiresExtractorProvider: PythonPackageRequiresExtractorProvider {
|
||||
internal class UvPackageRequiresExtractorProvider : PythonPackageRequiresExtractorProvider {
|
||||
override fun createExtractor(sdk: Sdk): PythonPackageRequirementExtractor? {
|
||||
val data = sdk.sdkAdditionalData as? UvSdkAdditionalData ?: return null
|
||||
return UvPackageRequirementExtractor(data.uvWorkingDirectory)
|
||||
|
||||
@@ -2,28 +2,25 @@ package com.jetbrains.python.uv.sdk.evolution
|
||||
|
||||
import com.intellij.openapi.ui.popup.ListSeparator
|
||||
import com.intellij.python.community.impl.uv.common.icons.PythonCommunityImplUVCommonIcons
|
||||
import com.jetbrains.python.Result
|
||||
import com.jetbrains.python.errorProcessing.PyResult
|
||||
import com.jetbrains.python.sdk.basePath
|
||||
import com.intellij.python.sdk.ui.evolution.sdk.EvoModuleSdk
|
||||
import com.intellij.python.sdk.ui.evolution.sdk.EvoSdk
|
||||
import com.intellij.python.sdk.ui.evolution.AddNewEnvAction
|
||||
import com.intellij.python.sdk.ui.evolution.SelectEnvAction
|
||||
import com.intellij.python.sdk.ui.evolution.sdk.EvoModuleSdk
|
||||
import com.intellij.python.sdk.ui.evolution.sdk.EvoSdk
|
||||
import com.intellij.python.sdk.ui.evolution.tool.pip.sdk.VenvEvoSdkManager
|
||||
import com.intellij.python.sdk.ui.evolution.ui.EvoSelectSdkProvider
|
||||
import com.intellij.python.sdk.ui.evolution.ui.components.EvoTreeLazyNodeElement
|
||||
import com.intellij.python.sdk.ui.evolution.ui.components.EvoTreeLeafElement
|
||||
import com.intellij.python.sdk.ui.evolution.ui.components.EvoTreeSection
|
||||
import com.jetbrains.python.PyBundle
|
||||
import com.jetbrains.python.icons.PythonIcons
|
||||
import com.jetbrains.python.Result
|
||||
import com.jetbrains.python.errorProcessing.PyResult
|
||||
import com.jetbrains.python.sdk.baseDir
|
||||
import com.jetbrains.python.sdk.uv.impl.getUvExecutable
|
||||
import com.jetbrains.python.venvReader.VirtualEnvReader
|
||||
import java.nio.file.Path
|
||||
import kotlin.collections.component1
|
||||
import kotlin.collections.component2
|
||||
|
||||
|
||||
internal class UvSelectSdkProvider() : EvoSelectSdkProvider {
|
||||
internal class UvSelectSdkProvider : EvoSelectSdkProvider {
|
||||
override fun getTreeElement(evoModuleSdk: EvoModuleSdk): EvoTreeLazyNodeElement {
|
||||
val icon = PythonCommunityImplUVCommonIcons.UV
|
||||
return EvoTreeLazyNodeElement("uv", icon) {
|
||||
@@ -34,7 +31,7 @@ internal class UvSelectSdkProvider() : EvoSelectSdkProvider {
|
||||
}.map { it.copy(icon = icon) }
|
||||
val envByFolders = environments.groupBy { it.pythonBinaryPath?.parent?.parent?.parent }.toMutableMap()
|
||||
envByFolders.putIfAbsent(
|
||||
evoModuleSdk.module.basePath?.let { Path.of(it) },
|
||||
evoModuleSdk.module.baseDir?.path?.let { Path.of(it) },
|
||||
listOf(EvoSdk(icon = icon, name = VirtualEnvReader.DEFAULT_VIRTUALENV_DIRNAME, pythonBinaryPath = null))
|
||||
)
|
||||
val envSections = envByFolders.map { (basePath, sdks) ->
|
||||
|
||||
@@ -285,7 +285,7 @@ class PySdkPathsTest {
|
||||
val module = projectModel.createModule(name)
|
||||
assertThat(PyUtil.getSourceRoots(module)).isEmpty()
|
||||
|
||||
module.rootManager.modifiableModel.apply {
|
||||
ModuleRootManager.getInstance(module).modifiableModel.apply {
|
||||
addContentEntry(moduleRoot)
|
||||
runWriteActionAndWait { commit() }
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user