mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
cleanup [python]: Fix a couple of VirtualEnvReader bottlenecks.
1. No need to check if file is directory: FS isn't atomic anyway, and we need to handle exceptions. Let's not do one more useless syscall which might be expensive on eel. 2. Check filename before reading it metadata (one more syscall) GitOrigin-RevId: 0fac159784c2c1d80c3418eb0d9c60a501662b7d
This commit is contained in:
committed by
intellij-monorepo-bot
parent
4cc9b0a3d3
commit
3e47d60be1
@@ -18,6 +18,8 @@ import org.jetbrains.annotations.ApiStatus
|
||||
import org.jetbrains.annotations.NonNls
|
||||
import org.jetbrains.annotations.TestOnly
|
||||
import java.io.IOException
|
||||
import java.nio.file.NoSuchFileException
|
||||
import java.nio.file.NotDirectoryException
|
||||
import java.nio.file.Path
|
||||
import kotlin.io.path.*
|
||||
|
||||
@@ -57,7 +59,7 @@ class VirtualEnvReader private constructor(
|
||||
*/
|
||||
@RequiresBackgroundThread
|
||||
fun findVEnvInterpreters(): List<PythonBinary> =
|
||||
findLocalInterpreters(getVEnvRootDir())
|
||||
findVenvsInDir(getVEnvRootDir())
|
||||
|
||||
@RequiresBackgroundThread
|
||||
fun getPyenvRootDir(eel: EelApi? = getLocalEelIfApp()): Directory {
|
||||
@@ -66,16 +68,26 @@ class VirtualEnvReader private constructor(
|
||||
|
||||
@RequiresBackgroundThread
|
||||
fun findPyenvInterpreters(): List<PythonBinary> =
|
||||
findLocalInterpreters(getPyenvVersionsDir())
|
||||
findVenvsInDir(getPyenvVersionsDir())
|
||||
|
||||
/**
|
||||
* List contents of [root] looking for envs there, returns all pythons it were able to find
|
||||
*/
|
||||
@RequiresBackgroundThread
|
||||
fun findLocalInterpreters(root: Directory): List<PythonBinary> {
|
||||
if (!root.isDirectory()) {
|
||||
return listOf()
|
||||
}
|
||||
fun findVenvsInDir(root: Directory): List<PythonBinary> {
|
||||
|
||||
val candidates: ArrayList<Path> = arrayListOf()
|
||||
for (dir in root.listDirectoryEntries()) {
|
||||
val children = try {
|
||||
root.listDirectoryEntries()
|
||||
}
|
||||
catch (_: NoSuchFileException) {
|
||||
return emptyList()
|
||||
}
|
||||
catch (_: NotDirectoryException) {
|
||||
return emptyList()
|
||||
}
|
||||
|
||||
for (dir in children) {
|
||||
findPythonInPythonRoot(dir)?.let { candidates.add(it) }
|
||||
}
|
||||
|
||||
@@ -120,19 +132,12 @@ class VirtualEnvReader private constructor(
|
||||
*/
|
||||
@RequiresBackgroundThread
|
||||
fun findPythonInPythonRoot(dir: PythonHomePath): PythonBinary? {
|
||||
if (!dir.isDirectory()) {
|
||||
return null
|
||||
}
|
||||
|
||||
val bin = dir.resolve("bin")
|
||||
if (bin.isDirectory()) {
|
||||
findInterpreter(bin)?.let { return it }
|
||||
}
|
||||
findInterpreter(bin)?.let { return it }
|
||||
|
||||
val scripts = dir.resolve("Scripts")
|
||||
if (scripts.isDirectory()) {
|
||||
findInterpreter(scripts)?.let { return it }
|
||||
}
|
||||
findInterpreter(scripts)?.let { return it }
|
||||
|
||||
return findInterpreter(dir)
|
||||
}
|
||||
@@ -170,10 +175,18 @@ class VirtualEnvReader private constructor(
|
||||
@RequiresBackgroundThread
|
||||
private fun findInterpreter(dir: Path): PythonBinary? {
|
||||
val pythonNames = when (forcedOs ?: dir.getEelDescriptor().osFamily) {
|
||||
EelOsFamily.Posix -> setOf("pypy", "python")
|
||||
EelOsFamily.Windows -> setOf("pypy.exe", "python.exe")
|
||||
EelOsFamily.Posix -> POSIX_BINS
|
||||
EelOsFamily.Windows -> WIN_BINS
|
||||
}
|
||||
return try {
|
||||
dir.listDirectoryEntries().firstOrNull { it.name.lowercase() in pythonNames && it.isRegularFile() }
|
||||
}
|
||||
catch (_: NotDirectoryException) {
|
||||
return null
|
||||
}
|
||||
catch (_: NoSuchFileException) {
|
||||
return null
|
||||
}
|
||||
return dir.listDirectoryEntries().firstOrNull { it.isRegularFile() && it.name.lowercase() in pythonNames }
|
||||
}
|
||||
|
||||
@RequiresBackgroundThread
|
||||
@@ -203,6 +216,8 @@ class VirtualEnvReader private constructor(
|
||||
@Suppress("VENV_IS_OK") // The only place it should be used in prod
|
||||
const val DEFAULT_VIRTUALENV_DIRNAME: String = ".venv"
|
||||
|
||||
private val POSIX_BINS = setOf("pypy", "python")
|
||||
private val WIN_BINS = setOf("pypy.exe", "python.exe")
|
||||
private fun getLocalEelIfApp(): EelApi? = if (ApplicationManager.getApplication() != null) localEel else null
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user