Skip to content

Commit

Permalink
To define whether folders are by default in the project, don't just c…
Browse files Browse the repository at this point in the history
…heck workspace, actually resolve the pythonpath from projects.
  • Loading branch information
fabioz committed Sep 21, 2024
1 parent 40385eb commit 1da5193
Show file tree
Hide file tree
Showing 14 changed files with 144 additions and 100 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ protected Set<String> getPythonPathFolders() {
IPythonPathNature pythonPathNature = pythonNature.getPythonPathNature();
Set<String> ret = new HashSet<>();
try {
ret.addAll(StringUtils.split(pythonPathNature.getOnlyProjectPythonPathStr(true), "|"));
ret.addAll(pythonPathNature.getOnlyProjectPythonPathStr(true));
} catch (CoreException e) {
Log.log(e);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -196,9 +196,7 @@ void createMypyProcess(IExternalCodeAnalysisStream out)
Collection<String> addToMypyPath = new HashSet<String>();
IModulesManager[] managersInvolved = nature.getAstManager().getModulesManager().getManagersInvolved(false);
for (IModulesManager iModulesManager : managersInvolved) {
for (String s : StringUtils
.split(iModulesManager.getNature().getPythonPathNature().getOnlyProjectPythonPathStr(true),
"|")) {
for (String s : iModulesManager.getNature().getPythonPathNature().getOnlyProjectPythonPathStr(true)) {
if (!s.isEmpty()) {
addToMypyPath.add(s);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -271,8 +271,7 @@ public void addProps(MarkerAnnotationAndPosition markerAnnotation, IAnalysisPref
//Discover the source folder where we should create the structure.

File editorFile = edit.getEditorFile();
String onlyProjectPythonPathStr = nature.getPythonPathNature().getOnlyProjectPythonPathStr(false);
List<String> split = StringUtils.splitAndRemoveEmptyTrimmed(onlyProjectPythonPathStr, '|');
List<String> split = nature.getPythonPathNature().getOnlyProjectPythonPathStr(false);
for (int i = 0; i < split.size(); i++) {
String fullPath = FileUtils.getFileAbsolutePath(split.get(i));
fullPath = PythonPathHelper.getDefaultPathStr(fullPath);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@

import org.eclipse.core.runtime.CoreException;
import org.python.pydev.core.IPythonNature;
import org.python.pydev.shared_core.string.StringUtils;
import org.python.pydev.shared_core.structure.Tuple3;

@SuppressWarnings({ "unchecked", "rawtypes" })
Expand Down Expand Up @@ -46,9 +45,8 @@ public List<String> getOnlyProjectPythonPathStr(IPythonNature nature, boolean ad
lst = onlyProjectPythonPathStrNonExternal;
}
if (lst == null) {
String onlyProjectPythonPathStr = nature.getPythonPathNature().getOnlyProjectPythonPathStr(addExternal);
HashSet<String> projectSourcePath = new HashSet<String>(StringUtils.splitAndRemoveEmptyTrimmed(
onlyProjectPythonPathStr, '|'));
HashSet<String> projectSourcePath = new HashSet<String>(
nature.getPythonPathNature().getOnlyProjectPythonPathStr(addExternal));
lst = new ArrayList<String>(projectSourcePath);
if (addExternal) {
onlyProjectPythonPathStrExternal = lst;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@
import org.python.pydev.plugin.nature.PythonNature;
import org.python.pydev.shared_core.callbacks.ICallback;
import org.python.pydev.shared_core.io.FileUtils;
import org.python.pydev.shared_core.string.StringUtils;
import org.python.pydev.shared_core.structure.Tuple;

/**
Expand Down Expand Up @@ -254,8 +253,7 @@ protected String getResolveModuleErr(IResource member) {
}

public String resolveModuleOnlyInProjectSources(String fileAbsolutePath, boolean addExternal) throws CoreException {
String onlyProjectPythonPathStr = this.nature.getPythonPathNature().getOnlyProjectPythonPathStr(addExternal);
List<String> pathItems = StringUtils.splitAndRemoveEmptyTrimmed(onlyProjectPythonPathStr, '|');
List<String> pathItems = this.nature.getPythonPathNature().getOnlyProjectPythonPathStr(addExternal);
List<String> filteredPathItems = filterDuplicatesPreservingOrder(pathItems);
return this.pythonPathHelper.resolveModule(fileAbsolutePath, false, filteredPathItems, project);
}
Expand Down Expand Up @@ -516,7 +514,7 @@ public List<String> getCompletePythonPath(IInterpreterInfo interpreter, IInterpr

boolean forceCheck = false;
ProjectModulesManager m2 = null;
String onlyProjectPythonPathStr = null;
IPythonPathNature pythonPathNature = null;
if (m instanceof ProjectModulesManager) {
long currentTimeMillis = System.currentTimeMillis();
m2 = (ProjectModulesManager) m;
Expand All @@ -526,9 +524,8 @@ public List<String> getCompletePythonPath(IInterpreterInfo interpreter, IInterpr
try {
IPythonNature n = m.getNature();
if (n != null) {
IPythonPathNature pythonPathNature = n.getPythonPathNature();
pythonPathNature = n.getPythonPathNature();
if (pythonPathNature != null) {
onlyProjectPythonPathStr = pythonPathNature.getOnlyProjectPythonPathStr(true);
m2.checkedPythonpathConsistency = currentTimeMillis;
forceCheck = true;
}
Expand All @@ -541,16 +538,22 @@ public List<String> getCompletePythonPath(IInterpreterInfo interpreter, IInterpr

if (forceCheck) {
//Check if it's actually correct and auto-fix if it's not.
List<String> parsed = PythonPathHelper.parsePythonPathFromStr(onlyProjectPythonPathStr, null);
if (m2.nature != null && !new HashSet<String>(parsed).equals(new HashSet<String>(pythonpath))) {
// Make it right at this moment (so any other place that calls it before the restore
//takes place has the proper version).
h.setPythonPath(parsed);

// Force a rebuild as the PythonPathHelper paths are not up to date.
m2.nature.rebuildPath();
List<String> parsed;
try {
parsed = pythonPathNature.getOnlyProjectPythonPathStr(true);
if (m2.nature != null
&& !new HashSet<String>(parsed).equals(new HashSet<String>(pythonpath))) {
// Make it right at this moment (so any other place that calls it before the restore
//takes place has the proper version).
h.setPythonPath(parsed);

// Force a rebuild as the PythonPathHelper paths are not up to date.
m2.nature.rebuildPath();
}
l.addAll(parsed); //add the proper paths
} catch (Exception e) {
Log.log(e);
}
l.addAll(parsed); //add the proper paths
} else {
l.addAll(pythonpath);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,20 @@
package org.python.pydev.ast.interpreter_managers;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
import org.python.pydev.core.log.Log;
import org.python.pydev.plugin.nature.PythonNature;
import org.python.pydev.shared_core.SharedCorePlugin;
import org.python.pydev.shared_core.io.FileUtils;

Expand Down Expand Up @@ -48,10 +54,19 @@ public boolean exists(String data) {
*/
public static boolean isChildOfRootPath(String data, Set<IPath> rootPaths) {
IPath path = Path.fromOSString(data);
java.nio.file.Path nativePath = new File(data).toPath();

for (IPath p : rootPaths) {
if (FileUtils.isPrefixOf(p, path)) {
return true;
}
try {
if (Files.isSameFile(nativePath, p.toFile().toPath())) {
return true;
}
} catch (IOException e) {
Log.log(e);
}
}
return false;
}
Expand All @@ -75,8 +90,22 @@ public static HashSet<IPath> getRootPaths() {
IPath location = iProject.getLocation();
if (location != null) {
IPath abs = location.makeAbsolute();
if (!FileUtils.isPrefixOf(rootLocation, abs)) {
rootPaths.add(abs);
rootPaths.add(abs);
}

PythonNature nature = PythonNature.getPythonNature(iProject);
if (nature != null) {
try {
List<String> splitted = nature.getPythonPathNature().getOnlyProjectPythonPathStr(true);
for (String s : splitted) {
try {
rootPaths.add(Path.fromOSString(FileUtils.getFileAbsolutePath(s)));
} catch (Exception e) {
Log.log(e);
}
}
} catch (CoreException e) {
Log.log(e);
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ protected RebuildPythonNatureModules() {
protected IStatus run(IProgressMonitor monitor) {
String paths;
try {
paths = pythonPathNature.getOnlyProjectPythonPathStr(true);
paths = StringUtils.join("|", pythonPathNature.getOnlyProjectPythonPathStr(true));
} catch (CoreException e1) {
Log.log(e1);
return Status.OK_STATUS;
Expand Down Expand Up @@ -671,11 +671,11 @@ private void init(String version, String projectPythonpath, String externalProje
protected IStatus run(IProgressMonitor monitor) {
try {
if (astManager != null) {
String pythonpath = pythonPathNature.getOnlyProjectPythonPathStr(true);
List<String> pythonpath = pythonPathNature.getOnlyProjectPythonPathStr(true);
PythonPathHelper pythonPathHelper = (PythonPathHelper) astManager.getModulesManager()
.getPythonPathHelper();
//If it doesn't match, rebuid the pythonpath!
if (!new HashSet<String>(PythonPathHelper.parsePythonPathFromStr(pythonpath, null))
if (!new HashSet<String>(pythonpath)
.equals(new HashSet<String>(pythonPathHelper.getPythonpath()))) {
rebuildPath();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
*/
package org.python.pydev.plugin.nature;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
Expand All @@ -25,6 +26,7 @@
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.QualifiedName;
import org.python.pydev.ast.codecompletion.revisited.PythonPathHelper;
import org.python.pydev.core.ExtensionHelper;
import org.python.pydev.core.ICodeCompletionASTManager;
import org.python.pydev.core.IInterpreterInfo;
Expand All @@ -33,6 +35,7 @@
import org.python.pydev.core.IPythonNature;
import org.python.pydev.core.IPythonPathNature;
import org.python.pydev.core.MisconfigurationException;
import org.python.pydev.core.ProjectMisconfiguredException;
import org.python.pydev.core.PropertiesHelper;
import org.python.pydev.core.PythonNatureWithoutProjectException;
import org.python.pydev.core.docutils.StringSubstitution;
Expand Down Expand Up @@ -151,15 +154,15 @@ private IModulesManager getProjectModulesManager() {
* @return the project pythonpath with complete paths in the filesystem.
*/
@Override
public String getOnlyProjectPythonPathStr(boolean addExternal) throws CoreException {
public List<String> getOnlyProjectPythonPathStr(boolean addExternal) throws CoreException {
String source = null;
String external = null;
String contributed = null;
IProject project = fProject;
PythonNature nature = fNature;

if (project == null || nature == null) {
return "";
return new ArrayList<>();
}

//Substitute with variables!
Expand Down Expand Up @@ -215,7 +218,8 @@ public String getOnlyProjectPythonPathStr(boolean addExternal) throws CoreExcept
if (external == null) {
external = "";
}
return buf.append("|").append(external).append("|").append(contributed).toString();
return PythonPathHelper.parsePythonPathFromStr(
buf.append("|").append(external).append("|").append(contributed).toString(), null);
}

/**
Expand Down Expand Up @@ -517,12 +521,19 @@ public Map<String, String> getVariableSubstitution(boolean addInterpreterInfoSub
Map<String, String> variableSubstitution;
if (addInterpreterInfoSubstitutions) {

IInterpreterInfo info = nature.getProjectInterpreter();
Properties stringSubstitutionVariables = info.getStringSubstitutionVariables(true);
if (stringSubstitutionVariables == null) {
try {
IInterpreterInfo info = nature.getProjectInterpreter();
Properties stringSubstitutionVariables = info.getStringSubstitutionVariables(true);
if (stringSubstitutionVariables == null) {
variableSubstitution = new HashMap<String, String>();
} else {
variableSubstitution = PropertiesHelper.createMapFromProperties(stringSubstitutionVariables);
}
} catch (ProjectMisconfiguredException e) {
Log.logInfo(
"Interpreter info still not fully configured (interpreter substitutions won't be available).",
e);
variableSubstitution = new HashMap<String, String>();
} else {
variableSubstitution = PropertiesHelper.createMapFromProperties(stringSubstitutionVariables);
}
} else {
variableSubstitution = new HashMap<String, String>();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ public String getProjectExternalSourcePath(boolean replaceVariables) throws Core
}

@Override
public String getOnlyProjectPythonPathStr(boolean addExternal) throws CoreException {
public List<String> getOnlyProjectPythonPathStr(boolean addExternal) throws CoreException {
throw new RuntimeException("Not implemented");
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
*/
/*
* Created on Jun 2, 2005
*
*
* @author Fabio Zadrozny
*/
package org.python.pydev.core;
Expand Down Expand Up @@ -34,29 +34,29 @@ public interface IPythonPathNature {
/**
* @param interpreter: this is the interpreter that should be used for getting the pythonpathString interpreter
* (if it is null, the default interpreter is used)
*
*
* @param manager this is the interpreter manager that contains the interpreter passed. It's needed so that we
* can get the actual pythonpath for the interpreter passed (needed for the system pythonpath info).
*
*
* @return the pythonpath (source and externals) for the project as a list of strings (always as paths
* in the filesystem properly substituted)
*/
public List<String> getCompleteProjectPythonPath(IInterpreterInfo interpreter, IInterpreterManager info);

/**
* @param addExternal if true, the external libraries will also be added (and not only the project
* @param addExternal if true, the external libraries will also be added (and not only the project
* source folders)
*
*
* @return the pythonpath (source and externals) as a string (paths separated by | ), and always as
* complete paths in the filesystem.
* @throws CoreException
*/
public String getOnlyProjectPythonPathStr(boolean addExternal) throws CoreException;
public List<String> getOnlyProjectPythonPathStr(boolean addExternal) throws CoreException;

/**
* Sets the project source path (paths are relative to the project location and are separated by | )
* Sets the project source path (paths are relative to the project location and are separated by | )
* It can contain variables to be substituted.
*
*
* @param newSourcePath
* @throws CoreException
*/
Expand All @@ -65,14 +65,14 @@ public interface IPythonPathNature {
/**
* Sets the project external source paths (those are full-paths for mapping to a file in the filesystem, separated by | ).
* It can contain variables to be substituted.
*
*
* @param newExternalSourcePath
* @throws CoreException
*/
public void setProjectExternalSourcePath(String newExternalSourcePath) throws CoreException;

/**
* @param replaceVariables if true, any variables must be substituted (note that the return should still be always
* @param replaceVariables if true, any variables must be substituted (note that the return should still be always
* interpreted relative to the project location)
* @return only the project source paths (paths are relative to the project location and are separated by | )
* @throws CoreException
Expand All @@ -89,7 +89,7 @@ public interface IPythonPathNature {
public List<String> getProjectExternalSourcePathAsList(boolean replaceVariables) throws CoreException;

/**
* @param replaceVariables if true, any variables must be substituted (note that the return should still be always
* @param replaceVariables if true, any variables must be substituted (note that the return should still be always
* interpreted relative to the project location)
* @return only the project source paths as a list of strings (paths are relative to the project location)
* @throws CoreException
Expand All @@ -99,7 +99,7 @@ public interface IPythonPathNature {
/**
* This is a method akin to getProjectSourcePathSet, but it will return an ordered map where
* we map the version with variables resolved to the version without variables resolved.
*
*
* It should be used when doing some PYTHONPATH manipulation based on the current values, so,
* we can keep the values with the variables when doing some operation while being able to check
* for the resolved paths to check if some item should be actually added or not.
Expand All @@ -112,15 +112,15 @@ public interface IPythonPathNature {
public void clearCaches();

/**
* This method sets a variable substitution so that the source folders (project and external) can be set
* This method sets a variable substitution so that the source folders (project and external) can be set
* based on those variables.
*
*
* E.g.: If a variable PLATFORM maps to win32, setting a source folder as /libs/${PLATFORM}/dlls, it will be
* resolved in the project as /libs/win32/dlls.
*
*
* Another example would be creating a varible MY_APP that maps to d:\bin\my_app, so, ${MY_APP}/libs would point to
* d:\bin\my_app/libs
*
*
* Note that this variables are set at the project level and are resolved later than at the system level, so,
* when performing the substitution, it should get the variables from the interpreter and override those with
* the project variables before actually resolving anything.
Expand Down
Loading

0 comments on commit 1da5193

Please sign in to comment.