mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-04-20 13:31:28 +07:00
fixup python plugin sdk configuration silent errors; fixup quick fix path association getting stuck
GitOrigin-RevId: e709f2063464bfc4b90f3acdf0c6b82277f2dc65
This commit is contained in:
committed by
intellij-monorepo-bot
parent
ad065be46a
commit
67a49445ef
@@ -40,9 +40,8 @@ import com.jetbrains.python.sdk.flavors.conda.CondaEnvSdkFlavor
|
||||
import com.jetbrains.python.sdk.flavors.conda.NewCondaEnvRequest
|
||||
import com.jetbrains.python.sdk.flavors.conda.PyCondaCommand
|
||||
import com.jetbrains.python.sdk.flavors.listCondaEnvironments
|
||||
import com.jetbrains.python.sdk.setAssociationToModule
|
||||
import com.jetbrains.python.sdk.setAssociationToModuleAsync
|
||||
import com.jetbrains.python.sdk.showSdkExecutionException
|
||||
import com.jetbrains.python.ui.pyModalBlocking
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import java.awt.BorderLayout
|
||||
@@ -56,14 +55,12 @@ import javax.swing.JPanel
|
||||
*/
|
||||
internal class PyEnvironmentYmlSdkConfiguration : PyProjectSdkConfigurationExtension {
|
||||
private val LOGGER = Logger.getInstance(PyEnvironmentYmlSdkConfiguration::class.java)
|
||||
|
||||
@RequiresBackgroundThread
|
||||
override fun createAndAddSdkForConfigurator(module: Module): Sdk? = createAndAddSdk(module, Source.CONFIGURATOR)
|
||||
|
||||
override fun getIntention(module: Module): @IntentionName String? = getEnvironmentYml(module)?.let {
|
||||
PyCharmCommunityCustomizationBundle.message("sdk.create.condaenv.suggestion")
|
||||
}
|
||||
|
||||
@RequiresBackgroundThread
|
||||
override fun createAndAddSdkForInspection(module: Module): Sdk? = createAndAddSdk(module, Source.INSPECTION)
|
||||
|
||||
@@ -123,7 +120,7 @@ internal class PyEnvironmentYmlSdkConfiguration : PyProjectSdkConfigurationExten
|
||||
ApplicationManager.getApplication().invokeAndWait {
|
||||
LOGGER.debug("Adding conda environment: ${sdk.homePath}, associated ${shared}}, module path ${basePath})")
|
||||
if (!shared) {
|
||||
pyModalBlocking { sdk.setAssociationToModule(module) }
|
||||
sdk.setAssociationToModuleAsync(module)
|
||||
}
|
||||
|
||||
SdkConfigurationUtil.addSdk(sdk)
|
||||
|
||||
@@ -380,37 +380,35 @@ python.sdk.new.project.environment.type=Environment type:
|
||||
python.sdk.new.error.no.absolute=Path must be absolute
|
||||
|
||||
# Poetry package manager and SDK
|
||||
python.sdk.poetry.executable.not.found=Poetry executable is not found
|
||||
python.sdk.poetry.executable=Poetry executable:
|
||||
python.sdk.poetry.select.executable.title=Select Path to Poetry Executable
|
||||
python.sdk.poetry.associated.project=Associated project:
|
||||
python.sdk.poetry.associated.module=Associated module:
|
||||
python.sdk.poetry.execution.exception.no.project.message=Cannot find the project associated with this Poetry environment
|
||||
python.sdk.poetry.execution.exception.no.poetry.message=Cannot find Poetry
|
||||
python.sdk.poetry.quickfix.fix.pipenv.name=Fix Poetry interpreter
|
||||
python.sdk.poetry.quickfix.use.pipenv.name=Use Poetry interpreter
|
||||
python.sdk.poetry.pip.file.lock.not.found=poetry.lock is not found
|
||||
python.sdk.poetry.pip.file.lock.out.of.date=poetry.lock is out of date
|
||||
python.sdk.poetry.pip.file.notification.content=Run <a href='#lock'>poetry lock</a> or <a href='#update'>poetry update</a>
|
||||
python.sdk.poetry.pip.file.notification.content.without.updating=Run <a href='#lock'>poetry lock</a>, <a href='#noupdate'>poetry lock --no-update</a> or <a href='#update'>poetry update</a>
|
||||
python.sdk.poetry.pip.file.watcher=pyproject.toml Watcher
|
||||
python.sdk.dialog.message.creating.virtual.environments.based.on.poetry.environments.not.supported=Creating virtual environments based on Poetry environments is not supported
|
||||
python.sdk.dialog.title.setting.up.poetry.environment=Setting up poetry environment
|
||||
python.sdk.intention.family.name.install.requirements.from.poetry.lock=Install requirements from poetry.lock
|
||||
python.sdk.inspection.message.version.outdated.latest=''{0}'' version {1} is outdated (latest: {2})
|
||||
python.sdk.dialog.message.cannot.find.script.file.please.run.poetry.install.before.executing.scripts=Cannot find a script file\nPlease run 'poetry install' before executing scripts
|
||||
python.sdk.dialog.title.poetry.scripts=Poetry Scripts
|
||||
python.sdk.poetry.action.run.script.text=Run ''{0}''
|
||||
python.sdk.inspection.message.poetry.interpreter.associated.with.another.project=Poetry interpreter is associated with another {0}: {1}
|
||||
python.sdk.inspection.message.poetry.interpreter.not.associated.with.any.project=Poetry interpreter is not associated with any {0}
|
||||
python.sdk.dialog.message.creating.virtual.environments.based.on.poetry.environments.not.supported=Creating virtual environments based on Poetry environments is not supported
|
||||
python.sdk.poetry.environment.panel.title=Poetry Environment
|
||||
python.sdk.poetry.install.packages.from.toml.checkbox.text=Install packages from pyproject.toml
|
||||
python.sdk.poetry.dialog.message.poetry.interpreter.has.been.already.added=Poetry interpreter has been already added, select ''{0}''
|
||||
python.sdk.inspection.message.version.outdated.latest=''{0}'' version {1} is outdated (latest: {2})
|
||||
python.sdk.intention.family.name.install.requirements.from.poetry.lock=Install requirements from poetry.lock
|
||||
python.sdk.poetry.associated.module=Associated module:
|
||||
python.sdk.poetry.associated.project=Associated project:
|
||||
python.sdk.poetry.dialog.add.new.environment.in.project.checkbox=Create an in-project environment
|
||||
python.sdk.poetry.environment.panel.title=Poetry Environment
|
||||
python.sdk.poetry.executable.not.found=Poetry executable is not found
|
||||
python.sdk.poetry.executable=Poetry executable:
|
||||
python.sdk.poetry.detecting.environments=Detecting poetry environments
|
||||
python.sdk.poetry.execution.exception.no.poetry.message=Cannot find Poetry
|
||||
python.sdk.poetry.install.packages.from.toml.checkbox.text=Install packages from pyproject.toml
|
||||
python.sdk.poetry.pip.file.lock.not.found=poetry.lock is not found
|
||||
python.sdk.poetry.pip.file.lock.out.of.date=poetry.lock is out of date
|
||||
python.sdk.poetry.pip.file.notification.content.without.updating=Run <a href='#lock'>poetry lock</a>, <a href='#noupdate'>poetry lock --no-update</a> or <a href='#update'>poetry update</a>
|
||||
python.sdk.poetry.pip.file.notification.content=Run <a href='#lock'>poetry lock</a> or <a href='#update'>poetry update</a>
|
||||
python.sdk.poetry.pip.file.notification.locking.without.updating=Locking poetry.lock without updating
|
||||
python.sdk.poetry.pip.file.notification.locking=Locking poetry.lock
|
||||
python.sdk.poetry.pip.file.notification.updating=Updating Poetry environment
|
||||
python.sdk.poetry.pip.file.watcher=pyproject.toml Watcher
|
||||
python.sdk.poetry.quickfix.use.pipenv.name=Use Poetry interpreter
|
||||
python.sdk.poetry.select.executable.title=Select Path to Poetry Executable
|
||||
python.sdk.progress.setting.up.environment=Setting up {0} environment
|
||||
|
||||
# UV
|
||||
python.sdk.dialog.message.creating.virtual.environments.based.on.uv.environments.not.supported=Creating virtual environments based on uv environments is not supported
|
||||
python.sdk.uv.setting.up.uv.environment=Setting up uv environment
|
||||
python.sdk.dialog.title.setting.up.uv.environment=Setting up uv environment
|
||||
python.sdk.inspection.message.uv.interpreter.associated.with.another.project=uv interpreter is associated with another {0}: {1}
|
||||
python.sdk.inspection.message.uv.interpreter.not.associated.with.any.project=uv interpreter is not associated with any {0}
|
||||
|
||||
@@ -45,13 +45,26 @@ fun Sdk.getOrCreateAdditionalData(): PythonSdkAdditionalData {
|
||||
return newData
|
||||
}
|
||||
|
||||
@Internal
|
||||
/**
|
||||
* Saves SDK to the project table if there is no sdk with same name
|
||||
*/
|
||||
|
||||
@Internal
|
||||
suspend fun Sdk.persist(): Unit = edtWriteAction {
|
||||
if (ProjectJdkTable.getInstance().findJdk(name) == null) { // Saving 2 SDKs with same name is an error
|
||||
getOrCreateAdditionalData() // additional data is always required
|
||||
ProjectJdkTable.getInstance().addJdk(this)
|
||||
}
|
||||
}
|
||||
|
||||
@Internal
|
||||
fun Sdk.persistSync() {
|
||||
ApplicationManager.getApplication().invokeAndWait {
|
||||
ApplicationManager.getApplication().runWriteAction {
|
||||
if (ProjectJdkTable.getInstance().findJdk(name) == null) { // Saving 2 SDKs with same name is an error
|
||||
getOrCreateAdditionalData() // additional data is always required
|
||||
ProjectJdkTable.getInstance().addJdk(this)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -11,6 +11,8 @@ import com.fasterxml.jackson.databind.SerializerProvider
|
||||
import com.fasterxml.jackson.databind.module.SimpleModule
|
||||
import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
|
||||
import com.google.common.io.Resources
|
||||
import com.intellij.openapi.application.ApplicationManager
|
||||
import com.intellij.openapi.application.runInEdt
|
||||
import com.intellij.openapi.application.writeAction
|
||||
import com.intellij.openapi.diagnostic.Logger
|
||||
import com.intellij.openapi.diagnostic.logger
|
||||
@@ -191,6 +193,28 @@ object SdksKeeper {
|
||||
private fun load() = configUrl?.let { Resources.toString(it, StandardCharsets.UTF_8) }
|
||||
}
|
||||
|
||||
// Non suspend version is required for all cases where it is possible to call it from quick-fixes,
|
||||
// as right now calling pyModuleBlocking from quick-fix is not allowed in EDT.
|
||||
@ApiStatus.Internal
|
||||
fun Sdk.setAssociationToModuleAsync(module: Module) {
|
||||
val path = module.basePath
|
||||
assert(path != null) { "Module $module has not paths, and can't be associated" }
|
||||
|
||||
val data = getOrCreateAdditionalData()
|
||||
.also {
|
||||
it.associatedModulePath = path
|
||||
}
|
||||
|
||||
val modificator = sdkModificator
|
||||
modificator.sdkAdditionalData = data
|
||||
|
||||
runInEdt {
|
||||
ApplicationManager.getApplication().runWriteAction {
|
||||
modificator.commitChanges()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ApiStatus.Internal
|
||||
suspend fun Sdk.setAssociationToModule(module: Module) {
|
||||
val path = module.basePath
|
||||
@@ -200,12 +224,10 @@ suspend fun Sdk.setAssociationToModule(module: Module) {
|
||||
|
||||
@ApiStatus.Internal
|
||||
suspend fun Sdk.setAssociationToPath(path: String?) {
|
||||
val data = getOrCreateAdditionalData().also {
|
||||
when {
|
||||
path != null -> it.associatedModulePath = path
|
||||
else -> it.associatedModulePath = null
|
||||
val data = getOrCreateAdditionalData()
|
||||
.also {
|
||||
it.associatedModulePath = path
|
||||
}
|
||||
}
|
||||
|
||||
val modificator = sdkModificator
|
||||
modificator.sdkAdditionalData = data
|
||||
@@ -213,4 +235,4 @@ suspend fun Sdk.setAssociationToPath(path: String?) {
|
||||
writeAction {
|
||||
modificator.commitChanges()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -99,7 +99,7 @@ public abstract class PythonSdkFlavor<D extends PyFlavorData> {
|
||||
/**
|
||||
* Flavors that are aware of some system pythons must return them there.
|
||||
*/
|
||||
@RequiresBackgroundThread
|
||||
@RequiresBackgroundThread(generateAssertion = false)
|
||||
protected @NotNull Collection<@NotNull Path> suggestLocalHomePathsImpl(final @Nullable Module module,
|
||||
final @Nullable UserDataHolder context) {
|
||||
return Collections.emptyList();
|
||||
@@ -108,7 +108,7 @@ public abstract class PythonSdkFlavor<D extends PyFlavorData> {
|
||||
/**
|
||||
* On local targets some flavors could be detected. It returns a path to python interpreters for such cases.
|
||||
*/
|
||||
@RequiresBackgroundThread
|
||||
@RequiresBackgroundThread(generateAssertion = false)
|
||||
public final @NotNull Collection<@NotNull Path> suggestLocalHomePaths(final @Nullable Module module,
|
||||
final @Nullable UserDataHolder context) {
|
||||
return suggestLocalHomePathsImpl(module, context).stream().filter(path -> {
|
||||
|
||||
@@ -249,7 +249,6 @@ fun showSdkExecutionException(sdk: Sdk?, e: ExecutionException, @NlsContexts.Dia
|
||||
}
|
||||
|
||||
@Internal
|
||||
|
||||
fun Sdk.isAssociatedWithModule(module: Module?): Boolean {
|
||||
val basePath = module?.basePath
|
||||
val associatedPath = associatedModulePath
|
||||
@@ -259,7 +258,6 @@ fun Sdk.isAssociatedWithModule(module: Module?): Boolean {
|
||||
}
|
||||
|
||||
@Internal
|
||||
|
||||
fun Sdk.isAssociatedWithAnotherModule(module: Module?): Boolean {
|
||||
val basePath = module?.basePath ?: return false
|
||||
val associatedPath = associatedModulePath ?: return false
|
||||
@@ -402,7 +400,7 @@ fun getInnerVirtualEnvRoot(sdk: Sdk): VirtualFile? {
|
||||
}
|
||||
}
|
||||
|
||||
@RequiresBackgroundThread
|
||||
@RequiresBackgroundThread(generateAssertion = false)
|
||||
internal fun suggestAssociatedSdkName(sdkHome: String, associatedPath: String?): String? {
|
||||
// please don't forget to update com.jetbrains.python.inspections.PyInterpreterInspection.Visitor#getSuitableSdkFix
|
||||
// after changing this method
|
||||
|
||||
@@ -46,7 +46,7 @@ import javax.swing.JPanel
|
||||
*
|
||||
*/
|
||||
class PyAddSdkDialog private constructor(
|
||||
private val project: Project?,
|
||||
private val project: Project,
|
||||
private val module: Module?,
|
||||
private val existingSdks: List<Sdk>,
|
||||
) : DialogWrapper(project) {
|
||||
@@ -340,7 +340,7 @@ class PyAddSdkDialog private constructor(
|
||||
private const val WIZARD_CARD_PANE = "Wizard"
|
||||
|
||||
@JvmStatic
|
||||
fun show(project: Project?, module: Module?, existingSdks: List<Sdk>, sdkAddedCallback: Consumer<Sdk?>) {
|
||||
fun show(project: Project, module: Module?, existingSdks: List<Sdk>, sdkAddedCallback: Consumer<Sdk?>) {
|
||||
val dialog = PyAddSdkDialog(project = project, module = module, existingSdks = existingSdks)
|
||||
dialog.init()
|
||||
|
||||
@@ -354,7 +354,7 @@ class PyAddSdkDialog private constructor(
|
||||
* `org.jetbrains.plugins.remote-run` plugin is disabled.
|
||||
*/
|
||||
private fun PyAddSdkProvider.safeCreateView(
|
||||
project: Project?,
|
||||
project: Project,
|
||||
module: Module?,
|
||||
existingSdks: List<Sdk>,
|
||||
context: UserDataHolder,
|
||||
|
||||
@@ -12,7 +12,7 @@ interface PyAddSdkProvider {
|
||||
/**
|
||||
* Returns [PyAddSdkView] if applicable.
|
||||
*/
|
||||
fun createView(project: Project?,
|
||||
fun createView(project: Project,
|
||||
module: Module?,
|
||||
newProjectPath: String?,
|
||||
existingSdks: List<Sdk>,
|
||||
|
||||
@@ -41,7 +41,7 @@ open class PyAddNewCondaEnvPanel(
|
||||
private val project: Project?,
|
||||
private val module: Module?,
|
||||
private val existingSdks: List<Sdk>,
|
||||
newProjectPath: String?,
|
||||
newProjectPath: String?
|
||||
) : PyAddNewEnvPanel(PythonInterpreterSelectionMode.BASE_CONDA) {
|
||||
override val envName: String = "Conda"
|
||||
override val panelName: String get() = PyBundle.message("python.add.sdk.panel.name.new.environment")
|
||||
@@ -121,11 +121,9 @@ open class PyAddNewCondaEnvPanel(
|
||||
val associatedPath = if (!shared) projectBasePath else null
|
||||
val sdk = createSdkByGenerateTask(task, existingSdks, null, associatedPath, null)
|
||||
if (!shared) {
|
||||
pyMayBeModalBlocking {
|
||||
when {
|
||||
newProjectPath != null -> sdk.setAssociationToPath(newProjectPath)
|
||||
module != null -> sdk.setAssociationToModule(module)
|
||||
}
|
||||
when {
|
||||
newProjectPath != null -> pyMayBeModalBlocking { sdk.setAssociationToPath(newProjectPath) }
|
||||
module != null -> sdk.setAssociationToModuleAsync(module)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -136,11 +134,11 @@ open class PyAddNewCondaEnvPanel(
|
||||
}
|
||||
|
||||
override fun getStatisticInfo(): InterpreterStatisticsInfo? {
|
||||
return InterpreterStatisticsInfo(InterpreterType.CONDAVENV,
|
||||
InterpreterTarget.LOCAL,
|
||||
false,
|
||||
makeSharedField.isSelected,
|
||||
false)
|
||||
return InterpreterStatisticsInfo(InterpreterType.CONDAVENV,
|
||||
InterpreterTarget.LOCAL,
|
||||
false,
|
||||
makeSharedField.isSelected,
|
||||
false)
|
||||
}
|
||||
|
||||
override fun addChangeListener(listener: Runnable) {
|
||||
|
||||
@@ -16,7 +16,7 @@ import javax.swing.JComponent
|
||||
/**
|
||||
* Use [PyAddTargetBasedSdkDialog.Companion.show] to instantiate and show the dialog.
|
||||
*/
|
||||
class PyAddTargetBasedSdkDialog private constructor(private val project: Project?,
|
||||
class PyAddTargetBasedSdkDialog private constructor(private val project: Project,
|
||||
private val module: Module?,
|
||||
private val existingSdks: List<Sdk>,
|
||||
private val targetEnvironmentConfiguration: TargetEnvironmentConfiguration?)
|
||||
@@ -58,7 +58,7 @@ class PyAddTargetBasedSdkDialog private constructor(private val project: Project
|
||||
* target.
|
||||
*/
|
||||
@JvmStatic
|
||||
fun show(project: Project?,
|
||||
fun show(project: Project,
|
||||
module: Module?,
|
||||
existingSdks: List<Sdk>,
|
||||
sdkAddedCallback: Consumer<Sdk?>,
|
||||
|
||||
@@ -45,7 +45,7 @@ import javax.swing.JPanel
|
||||
* The panel that is supposed to be used both for local and non-local target-based versions of "New Interpreter" dialog.
|
||||
*/
|
||||
internal class PyAddTargetBasedSdkPanel(
|
||||
private val project: Project?,
|
||||
private val project: Project,
|
||||
private val module: Module?,
|
||||
private val existingSdks: List<Sdk>,
|
||||
private val targetSupplier: Supplier<TargetEnvironmentConfiguration>?,
|
||||
|
||||
@@ -151,7 +151,7 @@ internal fun createSdkForTarget(
|
||||
if (PythonInterpreterTargetEnvironmentFactory.by(environmentConfiguration)?.needAssociateWithModule() == true) {
|
||||
// FIXME: multi module project support
|
||||
project?.modules?.firstOrNull()?.let {
|
||||
pyModalBlocking { sdk.setAssociationToModule(it) }
|
||||
sdk.setAssociationToModuleAsync(it)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -48,7 +48,7 @@ public final class MacPythonSdkFlavor extends CPythonSdkFlavor<PyFlavorData.Empt
|
||||
return PyFlavorData.Empty.class;
|
||||
}
|
||||
|
||||
@RequiresBackgroundThread
|
||||
@RequiresBackgroundThread(generateAssertion = false)
|
||||
@Override
|
||||
protected @NotNull Collection<@NotNull Path> suggestLocalHomePathsImpl(@Nullable Module module, @Nullable UserDataHolder context) {
|
||||
Set<Path> candidates = new HashSet<>();
|
||||
|
||||
@@ -45,7 +45,7 @@ public final class UnixPythonSdkFlavor extends CPythonSdkFlavor<PyFlavorData.Emp
|
||||
return PyFlavorData.Empty.class;
|
||||
}
|
||||
|
||||
@RequiresBackgroundThread
|
||||
@RequiresBackgroundThread(generateAssertion = false)
|
||||
@Override
|
||||
protected @NotNull Collection<@NotNull Path> suggestLocalHomePathsImpl(@Nullable Module module, @Nullable UserDataHolder context) {
|
||||
return getDefaultUnixPythons();
|
||||
|
||||
@@ -46,7 +46,7 @@ public final class VirtualEnvSdkFlavor extends CPythonSdkFlavor<PyFlavorData.Emp
|
||||
return PyFlavorData.Empty.class;
|
||||
}
|
||||
|
||||
@RequiresBackgroundThread
|
||||
@RequiresBackgroundThread(generateAssertion = false)
|
||||
@Override
|
||||
protected @NotNull Collection<@NotNull Path> suggestLocalHomePathsImpl(@Nullable Module module, @Nullable UserDataHolder context) {
|
||||
return ReadAction.compute(() -> {
|
||||
|
||||
@@ -85,7 +85,7 @@ public class WinPythonSdkFlavor extends CPythonSdkFlavor<PyFlavorData.Empty> {
|
||||
return PyFlavorData.Empty.class;
|
||||
}
|
||||
|
||||
@RequiresBackgroundThread
|
||||
@RequiresBackgroundThread(generateAssertion = false)
|
||||
@Override
|
||||
protected final @NotNull Collection<@NotNull Path> suggestLocalHomePathsImpl(final @Nullable Module module,
|
||||
final @Nullable UserDataHolder context) {
|
||||
@@ -95,7 +95,7 @@ public class WinPythonSdkFlavor extends CPythonSdkFlavor<PyFlavorData.Empty> {
|
||||
return ContainerUtil.map(candidates, Path::of);
|
||||
}
|
||||
|
||||
@RequiresBackgroundThread
|
||||
@RequiresBackgroundThread(generateAssertion = false)
|
||||
private void findInCandidatePaths(Set<String> candidates, String... exe_names) {
|
||||
@SuppressWarnings("TestOnlyProblems")
|
||||
var root = System.getProperty(ROOT_TO_SEARCH_PYTHON_IN, "C:\\");
|
||||
|
||||
@@ -58,7 +58,7 @@ public final class CondaEnvSdkFlavor extends CPythonSdkFlavor<PyCondaFlavorData>
|
||||
return PyCondaFlavorData.class;
|
||||
}
|
||||
|
||||
@RequiresBackgroundThread
|
||||
@RequiresBackgroundThread(generateAssertion = false)
|
||||
@Override
|
||||
protected @NotNull Collection<@NotNull Path> suggestLocalHomePathsImpl(@Nullable Module module, @Nullable UserDataHolder context) {
|
||||
// There is no such thing as "conda homepath" since conda doesn't store python path
|
||||
|
||||
@@ -9,10 +9,12 @@ import com.jetbrains.python.sdk.add.PyAddSdkProvider
|
||||
import com.jetbrains.python.sdk.pipenv.ui.PyAddPipEnvPanel
|
||||
|
||||
class PyAddPipEnvSdkProvider : PyAddSdkProvider {
|
||||
override fun createView(project: Project?,
|
||||
module: Module?,
|
||||
newProjectPath: String?,
|
||||
existingSdks: List<Sdk>,
|
||||
context: UserDataHolder) =
|
||||
override fun createView(
|
||||
project: Project,
|
||||
module: Module?,
|
||||
newProjectPath: String?,
|
||||
existingSdks: List<Sdk>,
|
||||
context: UserDataHolder
|
||||
) =
|
||||
PyAddPipEnvPanel(project, module, existingSdks, newProjectPath, context)
|
||||
}
|
||||
|
||||
@@ -7,8 +7,7 @@ import com.intellij.openapi.module.ModuleUtilCore
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.jetbrains.python.PyBundle
|
||||
import com.jetbrains.python.sdk.pythonSdk
|
||||
import com.jetbrains.python.sdk.setAssociationToModule
|
||||
import com.jetbrains.python.ui.pyModalBlocking
|
||||
import com.jetbrains.python.sdk.setAssociationToModuleAsync
|
||||
|
||||
/**
|
||||
* A quick-fix for setting up the pipenv for the module of the current PSI element.
|
||||
@@ -18,9 +17,9 @@ class PipEnvAssociationQuickFix : LocalQuickFix {
|
||||
|
||||
override fun getFamilyName() = quickFixName
|
||||
|
||||
override fun applyFix(project: Project, descriptor: ProblemDescriptor): Unit = pyModalBlocking {
|
||||
val element = descriptor.psiElement ?: return@pyModalBlocking
|
||||
val module = ModuleUtilCore.findModuleForPsiElement(element) ?: return@pyModalBlocking
|
||||
module.pythonSdk?.setAssociationToModule(module)
|
||||
override fun applyFix(project: Project, descriptor: ProblemDescriptor) {
|
||||
val element = descriptor.psiElement ?: return
|
||||
val module = ModuleUtilCore.findModuleForPsiElement(element) ?: return
|
||||
module.pythonSdk?.setAssociationToModuleAsync(module)
|
||||
}
|
||||
}
|
||||
@@ -6,18 +6,18 @@ import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.projectRoots.Sdk
|
||||
import com.intellij.openapi.util.UserDataHolder
|
||||
import com.jetbrains.python.sdk.add.PyAddSdkProvider
|
||||
import com.jetbrains.python.sdk.add.PyAddSdkView
|
||||
import com.jetbrains.python.sdk.poetry.ui.createPoetryPanel
|
||||
|
||||
|
||||
/**
|
||||
* This source code is edited by @koxudaxi Koudai Aono <koxudaxi@gmail.com>
|
||||
*/
|
||||
|
||||
class PyAddPoetrySdkProvider : PyAddSdkProvider {
|
||||
override fun createView(project: Project?,
|
||||
module: Module?,
|
||||
newProjectPath: String?,
|
||||
existingSdks: List<Sdk>,
|
||||
context: UserDataHolder) =
|
||||
createPoetryPanel(project, module, existingSdks, newProjectPath, context)
|
||||
override fun createView(
|
||||
project: Project,
|
||||
module: Module?,
|
||||
newProjectPath: String?,
|
||||
existingSdks: List<Sdk>,
|
||||
context: UserDataHolder
|
||||
): PyAddSdkView? {
|
||||
return createPoetryPanel(project, module, existingSdks, newProjectPath, context)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,8 +7,7 @@ import com.intellij.openapi.module.ModuleUtilCore
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.jetbrains.python.PyBundle
|
||||
import com.jetbrains.python.sdk.pythonSdk
|
||||
import com.jetbrains.python.sdk.setAssociationToModule
|
||||
import com.jetbrains.python.ui.pyModalBlocking
|
||||
import com.jetbrains.python.sdk.setAssociationToModuleAsync
|
||||
|
||||
/**
|
||||
* A quick-fix for setting up the poetry for the module of the current PSI element.
|
||||
@@ -18,9 +17,9 @@ class PoetryAssociationQuickFix: LocalQuickFix {
|
||||
|
||||
override fun getFamilyName() = quickFixName
|
||||
|
||||
override fun applyFix(project: Project, descriptor: ProblemDescriptor): Unit = pyModalBlocking {
|
||||
val element = descriptor.psiElement ?: return@pyModalBlocking
|
||||
val module = ModuleUtilCore.findModuleForPsiElement(element) ?: return@pyModalBlocking
|
||||
module.pythonSdk?.setAssociationToModule(module)
|
||||
override fun applyFix(project: Project, descriptor: ProblemDescriptor) {
|
||||
val element = descriptor.psiElement ?: return
|
||||
val module = ModuleUtilCore.findModuleForPsiElement(element) ?: return
|
||||
module.pythonSdk?.setAssociationToModuleAsync(module)
|
||||
}
|
||||
}
|
||||
@@ -16,7 +16,7 @@ import com.jetbrains.python.ui.pyModalBlocking
|
||||
import java.util.function.Supplier
|
||||
|
||||
fun createPoetryPanel(
|
||||
project: Project?,
|
||||
project: Project,
|
||||
module: Module?,
|
||||
existingSdks: List<Sdk>,
|
||||
newProjectPath: String?,
|
||||
|
||||
@@ -9,19 +9,20 @@ import com.intellij.util.ui.FormBuilder
|
||||
import com.jetbrains.python.PyBundle
|
||||
import com.jetbrains.python.PySdkBundle
|
||||
import com.jetbrains.python.sdk.*
|
||||
import com.jetbrains.python.sdk.add.PyAddSdkView
|
||||
import com.jetbrains.python.sdk.add.PySdkPathChoosingComboBox
|
||||
import com.jetbrains.python.sdk.add.PyAddSdkPanel
|
||||
import com.jetbrains.python.sdk.add.addInterpretersAsync
|
||||
import com.jetbrains.python.sdk.poetry.*
|
||||
import com.jetbrains.python.ui.pyMayBeModalBlocking
|
||||
import com.jetbrains.python.ui.pyModalBlocking
|
||||
import com.jetbrains.python.util.runWithModalBlockingOrInBackground
|
||||
import java.awt.BorderLayout
|
||||
import java.util.concurrent.ConcurrentHashMap
|
||||
import javax.swing.Icon
|
||||
|
||||
|
||||
class PyAddExistingPoetryEnvPanel(
|
||||
private val project: Project?,
|
||||
private val project: Project,
|
||||
private val module: Module?,
|
||||
private val existingSdks: List<Sdk>,
|
||||
override var newProjectPath: String?,
|
||||
@@ -41,9 +42,8 @@ class PyAddExistingPoetryEnvPanel(
|
||||
add(formPanel, BorderLayout.NORTH)
|
||||
addInterpretersAsync(sdkComboBox) {
|
||||
val existingSdkPaths = sdkHomes(existingSdks)
|
||||
|
||||
val moduleSdks = allModules(project).parallelStream().flatMap { module ->
|
||||
val sdks = pyModalBlocking {
|
||||
val sdks = pyMayBeModalBlocking {
|
||||
detectPoetryEnvs(module, existingSdkPaths, module.basePath)
|
||||
}.filterNot { it.isAssociatedWithAnotherModule(module) }
|
||||
|
||||
@@ -51,8 +51,8 @@ class PyAddExistingPoetryEnvPanel(
|
||||
sdks.stream()
|
||||
}.toList()
|
||||
|
||||
val rootSdks = pyModalBlocking {
|
||||
detectPoetryEnvs(module, existingSdkPaths, project?.basePath ?: newProjectPath)
|
||||
val rootSdks = pyMayBeModalBlocking {
|
||||
detectPoetryEnvs(module, existingSdkPaths, project.basePath ?: newProjectPath)
|
||||
}.filterNot { it.isAssociatedWithAnotherModule(module) }
|
||||
|
||||
val moduleSdkPaths = moduleSdks.map { it.name }.toSet()
|
||||
@@ -63,14 +63,15 @@ class PyAddExistingPoetryEnvPanel(
|
||||
}
|
||||
|
||||
override fun validateAll(): List<ValidationInfo> {
|
||||
return listOfNotNull(validateSdkComboBox(sdkComboBox, this))
|
||||
return emptyList()
|
||||
|
||||
}
|
||||
|
||||
override fun getOrCreateSdk(): Sdk? {
|
||||
return when (val sdk = sdkComboBox.selectedSdk) {
|
||||
is PyDetectedSdk -> {
|
||||
val mappedModule = sdkToModule[sdk.name] ?: module
|
||||
pyModalBlocking {
|
||||
runWithModalBlockingOrInBackground(project, msg = PyBundle.message("python.sdk.dialog.title.setting.up.poetry.environment")) {
|
||||
setupPoetrySdkUnderProgress(project, mappedModule, existingSdks, newProjectPath,
|
||||
getPythonExecutable(sdk.name), false, sdk.name).onSuccess {
|
||||
PySdkSettings.instance.preferredVirtualEnvBaseSdk = getPythonExecutable(sdk.name)
|
||||
@@ -80,12 +81,4 @@ class PyAddExistingPoetryEnvPanel(
|
||||
else -> sdk
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME: @Egor
|
||||
fun validateSdkComboBox(field: PySdkPathChoosingComboBox, view: PyAddSdkView): ValidationInfo? {
|
||||
return when (val sdk = field.selectedSdk) {
|
||||
null -> ValidationInfo(PySdkBundle.message("python.sdk.field.is.empty"), field)
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,26 +10,25 @@ import com.jetbrains.python.PyBundle
|
||||
import com.jetbrains.python.inspections.requirement.RunningPackagingTasksListener
|
||||
import com.jetbrains.python.packaging.PyPackageManagerUI
|
||||
import com.jetbrains.python.sdk.pythonSdk
|
||||
import com.jetbrains.python.sdk.setAssociationToModule
|
||||
import com.jetbrains.python.ui.pyModalBlocking
|
||||
import com.jetbrains.python.sdk.setAssociationToModuleAsync
|
||||
|
||||
internal class UvAssociationQuickFix : LocalQuickFix {
|
||||
private val quickFixName = PyBundle.message("python.sdk.quickfix.use.uv.name")
|
||||
|
||||
override fun getFamilyName() = quickFixName
|
||||
|
||||
override fun applyFix(project: Project, descriptor: ProblemDescriptor): Unit = pyModalBlocking {
|
||||
override fun applyFix(project: Project, descriptor: ProblemDescriptor) {
|
||||
val element = descriptor.psiElement
|
||||
if (element == null) {
|
||||
return@pyModalBlocking
|
||||
return
|
||||
}
|
||||
|
||||
val module = ModuleUtilCore.findModuleForPsiElement(element)
|
||||
if (module == null) {
|
||||
return@pyModalBlocking
|
||||
return
|
||||
}
|
||||
|
||||
module.pythonSdk?.setAssociationToModule(module)
|
||||
module.pythonSdk?.setAssociationToModuleAsync(module)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,7 +46,9 @@ class UvInstallQuickFix : LocalQuickFix {
|
||||
}
|
||||
}
|
||||
|
||||
override fun getFamilyName() = PyBundle.message("python.sdk.intention.family.name.install.requirements.from.uv.lock")
|
||||
override fun getFamilyName(): String {
|
||||
return PyBundle.message("python.sdk.intention.family.name.install.requirements.from.uv.lock")
|
||||
}
|
||||
|
||||
override fun applyFix(project: Project, descriptor: ProblemDescriptor) {
|
||||
val element = descriptor.psiElement
|
||||
|
||||
@@ -32,6 +32,7 @@ import com.jetbrains.python.sdk.PySdkSettings
|
||||
import com.jetbrains.python.sdk.PythonSdkCoroutineService
|
||||
import com.jetbrains.python.sdk.add.*
|
||||
import com.jetbrains.python.sdk.basePath
|
||||
import com.jetbrains.python.sdk.persistSync
|
||||
import com.jetbrains.python.sdk.uv.UV_ICON
|
||||
import com.jetbrains.python.sdk.uv.getPyProjectTomlForUv
|
||||
import com.jetbrains.python.sdk.uv.impl.detectUvExecutable
|
||||
@@ -41,6 +42,7 @@ import com.jetbrains.python.sdk.uv.setupNewUvSdkAndEnvUnderProgress
|
||||
import com.jetbrains.python.sdk.uv.validateSdks
|
||||
import com.jetbrains.python.statistics.InterpreterTarget
|
||||
import com.jetbrains.python.statistics.InterpreterType
|
||||
import com.jetbrains.python.util.runWithModalBlockingOrInBackground
|
||||
import com.jetbrains.python.venvReader.tryResolvePath
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
@@ -177,11 +179,12 @@ class PyAddNewUvPanel(
|
||||
setUvExecutable(it)
|
||||
}
|
||||
|
||||
val sdk = runBlockingCancellable {
|
||||
val sdk = runWithModalBlockingOrInBackground(project, PyBundle.message("python.sdk.uv.setting.up.uv.environment")) {
|
||||
setupNewUvSdkAndEnvUnderProgress(project, path, existingSdks, python)
|
||||
}
|
||||
|
||||
sdk.onSuccess {
|
||||
sdk.onSuccess { sdk ->
|
||||
sdk.persistSync();
|
||||
PySdkSettings.instance.preferredVirtualEnvBaseSdk = baseSdkField.selectedSdk.homePath
|
||||
}
|
||||
|
||||
@@ -240,7 +243,7 @@ class PyAddNewUvPanel(
|
||||
|
||||
class PyAddUvSdkProvider : PyAddSdkProvider {
|
||||
override fun createView(
|
||||
project: Project?,
|
||||
project: Project,
|
||||
module: Module?,
|
||||
newProjectPath: String?,
|
||||
existingSdks: List<Sdk>,
|
||||
|
||||
@@ -8,7 +8,6 @@ import com.intellij.util.concurrency.annotations.RequiresBlockingContext
|
||||
import com.intellij.util.concurrency.annotations.RequiresEdt
|
||||
import com.jetbrains.python.PySdkBundle
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import org.jetbrains.annotations.ApiStatus
|
||||
import javax.swing.SwingUtilities
|
||||
|
||||
/**
|
||||
@@ -25,9 +24,7 @@ fun <T> pyModalBlocking(modalTaskOwner: ModalTaskOwner = ModalTaskOwner.guess(),
|
||||
/**
|
||||
* It is *not* recommended to use this function. Prefer suspend functions.
|
||||
*/
|
||||
@ApiStatus.Obsolete
|
||||
@ApiStatus.Internal
|
||||
fun <T> pyMayBeModalBlocking(modalTaskOwner: ModalTaskOwner = ModalTaskOwner.guess(), code: suspend () -> T): T =
|
||||
internal fun <T> pyMayBeModalBlocking(modalTaskOwner: ModalTaskOwner = ModalTaskOwner.guess(), code: suspend () -> T): T =
|
||||
if (SwingUtilities.isEventDispatchThread()) {
|
||||
pyModalBlocking(modalTaskOwner, code)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user