mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-18 09:34:34 +07:00
[python] PY-84777 Use system pythons as a fallback for SDK configuration
There was a problem with detecting system-wide pythons, which relied on binary not being a part of conda env or virtualenv. But it led to unrelated Hatch and Poetry pythons automatically configured as interpreters in new projects. Another problem is that free-threaded python was chosen as default interpreter with highest priority because of the newest version. This change uses SystemPythonService to detect system pythons properly, also free-threaded python used as a default interpreter only if it's the only available option. Merge-request: IJ-MR-179008 Merged-by: Alexey Katsman <alexey.katsman@jetbrains.com> GitOrigin-RevId: 73bc98aed2918c44832b57f22b86c9c7d17a4301
This commit is contained in:
committed by
intellij-monorepo-bot
parent
9140cb4e7b
commit
a03643bb9c
+35
-21
@@ -124,7 +124,9 @@ class PythonSdkConfigurator : DirectoryProjectConfigurator {
|
||||
return@withContext
|
||||
}
|
||||
|
||||
if (findPreviousUsedSdk(existingSdks, project, module)) {
|
||||
val systemPythons = findSortedSystemPythons(module)
|
||||
|
||||
if (findPreviousUsedSdk(module, existingSdks, systemPythons)) {
|
||||
return@withContext
|
||||
}
|
||||
|
||||
@@ -132,48 +134,60 @@ class PythonSdkConfigurator : DirectoryProjectConfigurator {
|
||||
return@withContext
|
||||
}
|
||||
|
||||
findSystemWideSdk(module, existingSdks, project)
|
||||
findSystemWideSdk(module, existingSdks, systemPythons)
|
||||
}
|
||||
|
||||
private suspend fun findSystemWideSdk(
|
||||
module: Module,
|
||||
existingSdks: List<Sdk>,
|
||||
project: Project,
|
||||
systemPythons: List<SystemPython>,
|
||||
): Unit = reportRawProgress { indicator ->
|
||||
indicator.text(PyBundle.message("looking.for.system.interpreter"))
|
||||
thisLogger().debug("Looking for a system-wide interpreter")
|
||||
val eelDescriptor = module.project.getEelDescriptor()
|
||||
val homePaths = existingSdks
|
||||
.mapNotNull { sdk -> sdk.homePath?.let { homePath -> Path.of(homePath) } }
|
||||
.filter { it.getEelDescriptor() == eelDescriptor }
|
||||
SystemPythonService().findSystemPythons(eelDescriptor.toEelApi())
|
||||
.sortedWith(compareByDescending<SystemPython> { it.languageLevel }.thenBy { it.pythonBinary })
|
||||
.sortedByDescending { it.pythonBinary }
|
||||
.sortedByDescending { it.languageLevel }
|
||||
.firstOrNull { it.pythonBinary !in homePaths }?.let {
|
||||
thisLogger().debug { "Detected system-wide interpreter: $it" }
|
||||
withContext(Dispatchers.EDT) {
|
||||
SdkConfigurationUtil.createAndAddSDK(project, it.pythonBinary, PythonSdkType.getInstance())?.apply {
|
||||
thisLogger().debug { "Created system-wide interpreter: $this" }
|
||||
setReadyToUseSdk(project, module, this)
|
||||
}
|
||||
.mapNotNull { sdk -> sdk.takeIf { !it.isTargetBased() }?.homePath?.let { homePath -> Path.of(homePath) } }
|
||||
.filter { it.getEelDescriptor() == module.project.getEelDescriptor() }
|
||||
systemPythons.firstOrNull { it.pythonBinary !in homePaths }?.let {
|
||||
thisLogger().debug { "Detected system-wide interpreter: $it" }
|
||||
withContext(Dispatchers.EDT) {
|
||||
SdkConfigurationUtil.createAndAddSDK(module.project, it.pythonBinary, PythonSdkType.getInstance())?.apply {
|
||||
thisLogger().debug { "Created system-wide interpreter: $this" }
|
||||
setReadyToUseSdk(module.project, module, this)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun findPreviousUsedSdk(
|
||||
existingSdks: List<Sdk>,
|
||||
project: Project,
|
||||
module: Module,
|
||||
existingSdks: List<Sdk>,
|
||||
systemPythons: List<SystemPython>,
|
||||
): Boolean = reportRawProgress { indicator ->
|
||||
indicator.text(PyBundle.message("looking.for.previous.system.interpreter"))
|
||||
thisLogger().debug("Looking for the previously used system-wide interpreter")
|
||||
val sdk = mostPreferred(filterSystemWideSdks(existingSdks)) ?: return@reportRawProgress false
|
||||
val sdk = systemPythons.firstNotNullOfOrNull { systemPython ->
|
||||
existingSdks.firstOrNull { sdk ->
|
||||
val sdkHomePath = sdk.takeIf { !it.isTargetBased() }
|
||||
?.homePath
|
||||
?.let { Path.of(it) }
|
||||
?.takeIf { it.getEelDescriptor() == module.project.getEelDescriptor() }
|
||||
sdkHomePath == systemPython.pythonBinary
|
||||
}
|
||||
} ?: return@reportRawProgress false
|
||||
thisLogger().debug { "Previously used system-wide interpreter: $sdk" }
|
||||
setReadyToUseSdk(project, module, sdk)
|
||||
setReadyToUseSdk(module.project, module, sdk)
|
||||
return@reportRawProgress true
|
||||
}
|
||||
|
||||
private suspend fun findSortedSystemPythons(module: Module) = reportRawProgress { indicator ->
|
||||
indicator.text(PyBundle.message("looking.for.system.pythons"))
|
||||
SystemPythonService().findSystemPythons(module.project.getEelDescriptor().toEelApi())
|
||||
.sortedWith(
|
||||
// Free-threaded Python is unstable, we don't want to have it selected by default if we have alternatives
|
||||
compareBy<SystemPython> { it.pythonInfo.freeThreaded }.thenByDescending { it.pythonInfo.languageLevel }
|
||||
)
|
||||
}
|
||||
|
||||
private suspend fun findDefaultInterpreter(project: Project, module: Module): Boolean = reportRawProgress { indicator ->
|
||||
indicator.text(PyBundle.message("looking.for.default.interpreter"))
|
||||
thisLogger().debug("Looking for the default interpreter setting for a new project")
|
||||
|
||||
Reference in New Issue
Block a user