link/fix-system-pythons

[python]: `PathShortenerTest`: do not throw an exception for relative paths.

`EelPath` is always absolute, so we used to throw an exception if relative path was provided.

It makes no sense to substitute anything in relative path, so we simply return it as is.

[python]: `SystemPythonService`: remove duplicates.


Merge-request: IJ-MR-183231
Merged-by: Ilya Kazakevich <ilya.kazakevich@jetbrains.com>

GitOrigin-RevId: c391a55fda0f372184279e444e9188f71bceba3e
This commit is contained in:
Ilya Kazakevich
2025-11-24 21:21:09 +00:00
committed by intellij-monorepo-bot
parent 4280168782
commit 6d732f5624
3 changed files with 22 additions and 13 deletions
@@ -137,7 +137,10 @@ internal class SystemPythonServiceImpl(scope: CoroutineScope) : SystemPythonServ
}.toSet()
// Remove stale pythons from the cache
state.userProvidedPythons.removeAll(badPythons.map { it.pathString })
val newPaths = state.userProvidedPythons.distinct().toMutableList()
newPaths.removeAll(badPythons.map { it.pathString })
state.userProvidedPythons.clear()
state.userProvidedPythons.addAll(newPaths)
logger.info("pythons refreshed")
return@withContext result.sorted()
}
@@ -4,21 +4,18 @@ package com.intellij.python.junit5Tests.env.systemPython
import com.intellij.openapi.Disposable
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.diagnostic.fileLogger
import com.intellij.openapi.util.SystemInfo
import com.intellij.platform.eel.EelApi
import com.intellij.platform.eel.ExecuteProcessException
import com.intellij.platform.eel.ThrowsChecked
import com.intellij.platform.eel.provider.getEelDescriptor
import com.intellij.platform.eel.provider.utils.readWholeText
import com.intellij.platform.eel.spawnProcess
import com.intellij.python.community.impl.venv.createVenv
import com.intellij.python.community.services.systemPython.SystemPythonProvider
import com.intellij.python.community.services.systemPython.SystemPythonService
import com.intellij.python.community.services.systemPython.SystemPythonServiceImpl
import com.intellij.python.junit5Tests.assertFail
import com.intellij.python.junit5Tests.framework.env.PyEnvTestCase
import com.intellij.python.junit5Tests.framework.env.PythonBinaryPath
import com.intellij.python.junit5Tests.framework.winLockedFile.deleteCheckLocking
import com.intellij.python.junit5Tests.randomBinary
import com.intellij.testFramework.common.timeoutRunBlocking
import com.intellij.testFramework.junit5.RegistryKey
@@ -29,18 +26,12 @@ import com.jetbrains.python.PythonBinary
import com.jetbrains.python.Result
import com.jetbrains.python.errorProcessing.MessageError
import com.jetbrains.python.errorProcessing.PyResult
import com.jetbrains.python.getOrThrow
import com.jetbrains.python.sdk.flavors.PythonSdkFlavor
import com.jetbrains.python.venvReader.VirtualEnvReader
import kotlinx.coroutines.async
import org.hamcrest.MatcherAssert.assertThat
import org.hamcrest.Matchers.hasItem
import org.hamcrest.Matchers.not
import org.hamcrest.MatcherAssert
import org.hamcrest.Matchers
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.io.TempDir
import java.nio.file.Path
import kotlin.io.path.deleteExisting
import kotlin.io.path.pathString
import kotlin.time.Duration.Companion.minutes
@@ -68,6 +59,17 @@ class SystemPythonServiceShowCaseTest {
SystemPythonService().registerSystemPython(randomBinary).assertFail()
}
@Test
fun testRegister(@PythonBinaryPath path: PythonBinary): Unit = timeoutRunBlocking(10.minutes) {
val sut = SystemPythonService()
repeat(10) {
sut.registerSystemPython(path).orThrow()
}
val pythons = sut.findSystemPythons(forceRefresh = true).map { it.pythonBinary }
MatcherAssert.assertThat("No registered python", pythons, Matchers.hasItem(path))
Assertions.assertEquals(pythons.distinct().size, pythons.size, "Duplicates found")
}
@Test
fun testRefresh(@TestDisposable disposable: Disposable): Unit = timeoutRunBlocking(10.minutes) {
val provider = CountingTestProvider(Result.failure(MessageError("...")))