diff --git a/python/openapi/src/com/jetbrains/python/venvReader/VirtualEnvReader.kt b/python/openapi/src/com/jetbrains/python/venvReader/VirtualEnvReader.kt index 07583660808b..37baab199da5 100644 --- a/python/openapi/src/com/jetbrains/python/venvReader/VirtualEnvReader.kt +++ b/python/openapi/src/com/jetbrains/python/venvReader/VirtualEnvReader.kt @@ -25,6 +25,12 @@ class VirtualEnvReader( else setOf("pypy", "python") + private val binFolderName = if (isWindows) { + "Scripts" + } else { + "bin" + } + /** * Dir with virtual envs */ @@ -118,6 +124,28 @@ class VirtualEnvReader( return findInterpreter(dir) } + fun getVenvRootPath(path: Path): Path? { + val bin = path.parent + + if (bin == null || bin.fileName.pathString != binFolderName) { + return null + } + + val venv = bin.parent + + if (venv == null) { + return null + } + + val root = venv.parent + + if (root == null) { + return null + } + + return root + } + /** * Looks for python binary among directory entries */ @@ -144,5 +172,6 @@ class VirtualEnvReader( */ const val DEFAULT_VIRTUALENVS_DIR: String = ".virtualenvs" const val DEFAULT_VIRTUALENV_DIRNAME: String = ".venv" + } } \ No newline at end of file diff --git a/python/src/com/jetbrains/python/sdk/add/v2/uv/UvExistingEnvironmentSelector.kt b/python/src/com/jetbrains/python/sdk/add/v2/uv/UvExistingEnvironmentSelector.kt index 8d77c1bce47a..ee741c715572 100644 --- a/python/src/com/jetbrains/python/sdk/add/v2/uv/UvExistingEnvironmentSelector.kt +++ b/python/src/com/jetbrains/python/sdk/add/v2/uv/UvExistingEnvironmentSelector.kt @@ -19,6 +19,7 @@ import com.jetbrains.python.sdk.uv.isUv import com.jetbrains.python.sdk.uv.setupExistingEnvAndSdk import com.jetbrains.python.statistics.InterpreterType import com.jetbrains.python.statistics.version +import com.jetbrains.python.venvReader.VirtualEnvReader import com.jetbrains.python.venvReader.tryResolvePath import java.nio.file.Path import kotlin.io.path.pathString @@ -44,13 +45,15 @@ internal class UvExistingEnvironmentSelector(model: PythonMutableTargetAddInterp return Result.success(existingSdk) } - val existingWorkingDir = existingSdk?.associatedModulePath?.let { tryResolvePath(it) } - val usePip = existingWorkingDir != null && !existingSdk.isUv + val workingDirectory = + VirtualEnvReader().getVenvRootPath(selectedInterpreterPath) + ?: tryResolvePath(existingSdk?.associatedModulePath) + ?: projectDir return setupExistingEnvAndSdk( envExecutable = selectedInterpreterPath, - envWorkingDir = existingWorkingDir, - usePip = usePip, + envWorkingDir = workingDirectory, + usePip = existingSdk?.isUv == true, projectDir = projectDir, existingSdks = allSdk.toList() ) diff --git a/python/src/com/jetbrains/python/sdk/uv/UvExt.kt b/python/src/com/jetbrains/python/sdk/uv/UvExt.kt index ecc16a0193ca..e601243e593e 100644 --- a/python/src/com/jetbrains/python/sdk/uv/UvExt.kt +++ b/python/src/com/jetbrains/python/sdk/uv/UvExt.kt @@ -52,7 +52,7 @@ suspend fun setupNewUvSdkAndEnv( suspend fun setupExistingEnvAndSdk( envExecutable: Path, - envWorkingDir: Path?, + envWorkingDir: Path, usePip: Boolean, projectDir: Path, existingSdks: List, @@ -61,7 +61,7 @@ suspend fun setupExistingEnvAndSdk( envExecutable, existingSdks, projectDir.toString(), - suggestedSdkName(projectDir), + suggestedSdkName(envWorkingDir), UvSdkAdditionalData(envWorkingDir, usePip)) return sdk