From 066ffff77cc09ea907f4d47e89c6ee5df35d02ee Mon Sep 17 00:00:00 2001 From: Fabio Zadrozny Date: Sun, 10 Nov 2024 09:10:16 -0300 Subject: [PATCH] Improve heuristic which determines if a folder should be added to the interpreter pythonpath or not to consider virtual envs in the project itself. --- .../DefaultPathsForInterpreterInfo.java | 19 +++++++++++++++ .../interpreter_managers/InterpreterInfo.java | 24 ++++++++++++++++--- 2 files changed, 40 insertions(+), 3 deletions(-) diff --git a/plugins/org.python.pydev.ast/src/org/python/pydev/ast/interpreter_managers/DefaultPathsForInterpreterInfo.java b/plugins/org.python.pydev.ast/src/org/python/pydev/ast/interpreter_managers/DefaultPathsForInterpreterInfo.java index c47d6158e0..567f6743ff 100644 --- a/plugins/org.python.pydev.ast/src/org/python/pydev/ast/interpreter_managers/DefaultPathsForInterpreterInfo.java +++ b/plugins/org.python.pydev.ast/src/org/python/pydev/ast/interpreter_managers/DefaultPathsForInterpreterInfo.java @@ -45,6 +45,10 @@ public boolean selectByDefault(String data) { return !isChildOfRootPath(data, rootPaths); } + public boolean forceDeselect(String data) { + return isRootPath(data, rootPaths); + } + public boolean exists(String data) { return new File(data).exists(); } @@ -74,6 +78,21 @@ public static boolean isChildOfRootPath(String data, Set rootPaths) { return false; } + public static boolean isRootPath(String data, Set rootPaths) { + java.nio.file.Path nativePath = new File(data).toPath(); + + for (IPath p : rootPaths) { + try { + if (Files.isSameFile(nativePath, p.toFile().toPath())) { + return true; + } + } catch (IOException e) { + Log.log(e); + } + } + return false; + } + /** * Creates a Set of the root paths of all projects (and the workspace root itself). * @return A HashSet of root paths. diff --git a/plugins/org.python.pydev.ast/src/org/python/pydev/ast/interpreter_managers/InterpreterInfo.java b/plugins/org.python.pydev.ast/src/org/python/pydev/ast/interpreter_managers/InterpreterInfo.java index 44bf3e7996..6283a270a5 100644 --- a/plugins/org.python.pydev.ast/src/org/python/pydev/ast/interpreter_managers/InterpreterInfo.java +++ b/plugins/org.python.pydev.ast/src/org/python/pydev/ast/interpreter_managers/InterpreterInfo.java @@ -35,6 +35,7 @@ import org.eclipse.core.runtime.Assert; import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.Path; import org.eclipse.core.runtime.SafeRunner; @@ -375,6 +376,8 @@ public static InterpreterInfo fromString(String received, boolean askUserInOutPa DefaultPathsForInterpreterInfo defaultPaths = new DefaultPathsForInterpreterInfo( resolvingInterpreter); + Set pythonHomePaths = new HashSet<>(); + for (int j = 0; j < xmlNodes.getLength(); j++) { Node xmlChild = xmlNodes.item(j); String name = xmlChild.getNodeName(); @@ -388,6 +391,14 @@ public static InterpreterInfo fromString(String received, boolean askUserInOutPa } else if ("executable".equals(name)) { infoExecutable = data; + // Handling of python inside of project. + File pythonExecutableFile = new File(infoExecutable); + File pythonHome = pythonExecutableFile.getParentFile(); + if (new File(pythonHome, "pyenv.cfg").exists()) { + pythonHome = pythonHome.getParentFile(); + } + pythonHomePaths.add(Path.fromOSString(pythonHome.toString())); + } else if ("vmArgs".equals(name)) { infoVmArgs = data; @@ -410,10 +421,17 @@ public static InterpreterInfo fromString(String received, boolean askUserInOutPa if (askUserInOutPath) { toAsk.add(data); } - //Select only if path is not child of a root path - if (defaultPaths.selectByDefault(data)) { - selection.add(data); + + if (!defaultPaths.forceDeselect(data)) { // It's directly a project source folder (don't add it). + // If it's site-package, in python home or not under a source folder add it. + if (data.contains("site-packages") + || (DefaultPathsForInterpreterInfo + .isChildOfRootPath(data, pythonHomePaths)) + || defaultPaths.selectByDefault(data)) { + selection.add(data); + } } + } } else {