mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
PY-87281 Support versioned Python binaries
PY-87081 Prefer shortest Python binary name when resolving interpreters in virtual environments. PY-87281 Support versioned Python binaries (python3, python3.13, pypy3, etc.) Replace hardcoded Python binary name sets with regex patterns to match versioned executables like python3.13, python3.11.5, pypy3.10. Merge-request: IJ-MR-189909 Merged-by: Timur Malanin <timur.malanin@jetbrains.com> GitOrigin-RevId: f60b1c15b75e63cd96fd21c087b051c38ab095fe
This commit is contained in:
committed by
intellij-monorepo-bot
parent
7ef55b2554
commit
7e6ea0e505
@@ -138,8 +138,8 @@ class VirtualEnvReader private constructor(
|
||||
*/
|
||||
@RequiresBackgroundThread
|
||||
fun findPythonInPythonRoot(pathOrDir: PythonHomePath): PythonBinary? {
|
||||
val pythonNames = getPythonBinaryNames(pathOrDir.osFamily)
|
||||
if (pathOrDir.isRegularFile() && pathOrDir.name.lowercase() in pythonNames) {
|
||||
val pythonPattern = getPythonBinaryPattern(pathOrDir.osFamily)
|
||||
if (pathOrDir.isRegularFile() && pythonPattern.matches(pathOrDir.name)) {
|
||||
return pathOrDir
|
||||
}
|
||||
|
||||
@@ -188,17 +188,22 @@ class VirtualEnvReader private constructor(
|
||||
}
|
||||
|
||||
/**
|
||||
* Looks for python binary among directory entries
|
||||
* Looks for python binary among directory entries.
|
||||
* Prefers the shortest name (e.g., "python" over "python3.12") to ensure consistent results,
|
||||
* since virtual environments create multiple symlinks (python, python3, python3.12)
|
||||
* and Files.newDirectoryStream() order is undefined.
|
||||
*/
|
||||
@RequiresBackgroundThread
|
||||
private fun findInterpreter(dir: Path): PythonBinary? =
|
||||
try {
|
||||
Files.newDirectoryStream(dir).use { stream ->
|
||||
val pythonNames = getPythonBinaryNames(forcedOs ?: dir.osFamily)
|
||||
stream.firstOrNull {
|
||||
it.name.lowercase() in pythonNames &&
|
||||
it.isRegularFile()
|
||||
}
|
||||
val pythonPattern = getPythonBinaryPattern(forcedOs ?: dir.osFamily)
|
||||
|
||||
val candidates = stream.filter {
|
||||
it.isRegularFile() && pythonPattern.matches(it.name)
|
||||
}.toList()
|
||||
|
||||
candidates.minByOrNull { it.name.length }
|
||||
}
|
||||
|
||||
}
|
||||
@@ -235,16 +240,20 @@ 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 val POSIX_PYTHON_PATTERN = Regex("^(pypy|python)(\\d+(\\.\\d+)*)?$")
|
||||
private val WIN_PYTHON_PATTERN = Regex("^(pypy|python)(\\d+(\\.\\d+)*)?\\.exe$", RegexOption.IGNORE_CASE)
|
||||
private fun getLocalEelIfApp(): EelApi? = if (ApplicationManager.getApplication() != null) localEel else null
|
||||
|
||||
private fun getPythonBinaryNames(osFamily: EelOsFamily): Set<String> {
|
||||
val pythonNames = when (osFamily) {
|
||||
EelOsFamily.Posix -> POSIX_BINS
|
||||
EelOsFamily.Windows -> WIN_BINS
|
||||
/**
|
||||
* Returns a regex pattern that matches Python binary names.
|
||||
* Matches: python, python3, python3.X, python3.X.Y, python3.X.Y.Z, etc., pypy, pypy3, pypy3.X, pypy3.X.Y, etc.
|
||||
* (and .exe versions on Windows).
|
||||
*/
|
||||
private fun getPythonBinaryPattern(osFamily: EelOsFamily): Regex {
|
||||
return when (osFamily) {
|
||||
EelOsFamily.Posix -> POSIX_PYTHON_PATTERN
|
||||
EelOsFamily.Windows -> WIN_PYTHON_PATTERN
|
||||
}
|
||||
return pythonNames
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user