Skip to content

Commit

Permalink
Fix recursion error that could happen in race condition when restorin…
Browse files Browse the repository at this point in the history
…g interpreter.
  • Loading branch information
fabioz committed Sep 28, 2024
1 parent cfcd7d0 commit 9b27249
Show file tree
Hide file tree
Showing 22 changed files with 70 additions and 53 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(pythonPathNature.getOnlyProjectPythonPathStr(true));
ret.addAll(pythonPathNature.getOnlyProjectPythonPathStr(true, true));
} catch (CoreException e) {
Log.log(e);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,8 @@ void createMypyProcess(IExternalCodeAnalysisStream out)
Collection<String> addToMypyPath = new HashSet<String>();
IModulesManager[] managersInvolved = nature.getAstManager().getModulesManager().getManagersInvolved(false);
for (IModulesManager iModulesManager : managersInvolved) {
for (String s : iModulesManager.getNature().getPythonPathNature().getOnlyProjectPythonPathStr(true)) {
for (String s : iModulesManager.getNature().getPythonPathNature().getOnlyProjectPythonPathStr(true,
true)) {
if (!s.isEmpty()) {
addToMypyPath.add(s);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -273,7 +273,7 @@ public void addProps(MarkerAnnotationAndPosition markerAnnotation, IAnalysisPref
//Discover the source folder where we should create the structure.

File editorFile = edit.getEditorFile();
List<String> split = nature.getPythonPathNature().getOnlyProjectPythonPathStr(false);
List<String> split = nature.getPythonPathNature().getOnlyProjectPythonPathStr(false, true);
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 @@ -399,7 +399,7 @@ private HierarchyNodeModel assertIsIn(String name, String modName, List<Hierarch
String errorMsg = "Unable to find node with name:" + name +
" mod:" + modName +
"\nAvailable:" + available + "\n\nPythonpath: "
+ nature.getPythonPathNature().getOnlyProjectPythonPathStr(true) + "\n" +
+ nature.getPythonPathNature().getOnlyProjectPythonPathStr(true, true) + "\n" +
"Found possible references: " + StringUtils.join("\n", findPossibleReferences);

fail(errorMsg);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ public List<String> getOnlyProjectPythonPathStr(IPythonNature nature, boolean ad
}
if (lst == null) {
HashSet<String> projectSourcePath = new HashSet<String>(
nature.getPythonPathNature().getOnlyProjectPythonPathStr(addExternal));
nature.getPythonPathNature().getOnlyProjectPythonPathStr(addExternal, true));
lst = new ArrayList<String>(projectSourcePath);
if (addExternal) {
onlyProjectPythonPathStrExternal = lst;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -253,7 +253,7 @@ protected String getResolveModuleErr(IResource member) {
}

public String resolveModuleOnlyInProjectSources(String fileAbsolutePath, boolean addExternal) throws CoreException {
List<String> pathItems = this.nature.getPythonPathNature().getOnlyProjectPythonPathStr(addExternal);
List<String> pathItems = this.nature.getPythonPathNature().getOnlyProjectPythonPathStr(addExternal, true);
List<String> filteredPathItems = filterDuplicatesPreservingOrder(pathItems);
return this.pythonPathHelper.resolveModule(fileAbsolutePath, false, filteredPathItems, project);
}
Expand Down Expand Up @@ -540,7 +540,7 @@ public List<String> getCompletePythonPath(IInterpreterInfo interpreter, IInterpr
//Check if it's actually correct and auto-fix if it's not.
List<String> parsed;
try {
parsed = pythonPathNature.getOnlyProjectPythonPathStr(true);
parsed = pythonPathNature.getOnlyProjectPythonPathStr(true, 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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -280,7 +280,7 @@ public IImageHandle get(String key) {
if (newInterpreterInfo == null) {
continue;
}
DefaultPathsForInterpreterInfo defaultPaths = new DefaultPathsForInterpreterInfo();
DefaultPathsForInterpreterInfo defaultPaths = new DefaultPathsForInterpreterInfo(false);

OrderedSet<String> newEntries = new OrderedSet<String>(newInterpreterInfo.getPythonPath());
newEntries.removeAll(internalInfo.getPythonPath());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,11 @@ public class DefaultPathsForInterpreterInfo {

private final Set<IPath> rootPaths;

public DefaultPathsForInterpreterInfo() {
rootPaths = getRootPaths();
public DefaultPathsForInterpreterInfo(boolean resolvingInterpreter) {
boolean addInterpreterInfoSubstitutions = !resolvingInterpreter;
// When resolving the interpreter, we can't try to resolve variables from the
// interpreter itself as we could get into a recursion error.
rootPaths = getRootPaths(addInterpreterInfoSubstitutions);

}

Expand Down Expand Up @@ -75,7 +78,7 @@ public static boolean isChildOfRootPath(String data, Set<IPath> rootPaths) {
* Creates a Set of the root paths of all projects (and the workspace root itself).
* @return A HashSet of root paths.
*/
public static HashSet<IPath> getRootPaths() {
public static HashSet<IPath> getRootPaths(boolean addInterpreterInfoSubstitutions) {
HashSet<IPath> rootPaths = new HashSet<IPath>();
if (SharedCorePlugin.inTestMode()) {
return rootPaths;
Expand All @@ -96,7 +99,8 @@ public static HashSet<IPath> getRootPaths() {
PythonNature nature = PythonNature.getPythonNature(iProject);
if (nature != null) {
try {
List<String> splitted = nature.getPythonPathNature().getOnlyProjectPythonPathStr(true);
List<String> splitted = nature.getPythonPathNature().getOnlyProjectPythonPathStr(true,
addInterpreterInfoSubstitutions);
for (String s : splitted) {
try {
rootPaths.add(Path.fromOSString(FileUtils.getFileAbsolutePath(s)));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -371,7 +371,9 @@ public static InterpreterInfo fromString(String received, boolean askUserInOutPa
List<String> predefinedPaths = new ArrayList<String>();
Properties stringSubstitutionVars = new Properties();

DefaultPathsForInterpreterInfo defaultPaths = new DefaultPathsForInterpreterInfo();
boolean resolvingInterpreter = true;
DefaultPathsForInterpreterInfo defaultPaths = new DefaultPathsForInterpreterInfo(
resolvingInterpreter);

for (int j = 0; j < xmlNodes.getLength(); j++) {
Node xmlChild = xmlNodes.item(j);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,11 @@ public URI getFileAsURI() {

} else if (file instanceof IFile) {
IFile f = (IFile) file;
return f.getRawLocationURI();
URI rawLocationURI = f.getRawLocationURI();
if (rawLocationURI != null) {
return rawLocationURI;
}
return f.getLocationURI();

} else if (file instanceof IPath) {
IPath path = (IPath) file;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ private static Map<String, String> getDefaultSystemEnv(DebugPlugin defaultPlugin
String translated = value;
if (nature != null) {
try {
StringSubstitution stringSubstitution = new StringSubstitution(nature);
StringSubstitution stringSubstitution = new StringSubstitution(nature, true);
translated = stringSubstitution.performStringSubstitution(value, false);
} catch (Exception e) {
Log.log(e);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,9 @@ protected RebuildPythonNatureModules() {
protected IStatus run(IProgressMonitor monitor) {
String paths;
try {
paths = StringUtils.join("|", pythonPathNature.getOnlyProjectPythonPathStr(true));
boolean addInterpreterInfoSubstitutions = true;
paths = StringUtils.join("|",
pythonPathNature.getOnlyProjectPythonPathStr(true, addInterpreterInfoSubstitutions));
} catch (CoreException e1) {
Log.log(e1);
return Status.OK_STATUS;
Expand Down Expand Up @@ -671,7 +673,7 @@ private void init(String version, String projectPythonpath, String externalProje
protected IStatus run(IProgressMonitor monitor) {
try {
if (astManager != null) {
List<String> pythonpath = pythonPathNature.getOnlyProjectPythonPathStr(true);
List<String> pythonpath = pythonPathNature.getOnlyProjectPythonPathStr(true, true);
PythonPathHelper pythonPathHelper = (PythonPathHelper) astManager.getModulesManager()
.getPythonPathHelper();
//If it doesn't match, rebuid the pythonpath!
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,8 @@ private IModulesManager getProjectModulesManager() {
* @return the project pythonpath with complete paths in the filesystem.
*/
@Override
public List<String> getOnlyProjectPythonPathStr(boolean addExternal) throws CoreException {
public List<String> getOnlyProjectPythonPathStr(boolean addExternal, boolean addInterpreterInfoSubstitutions)
throws CoreException {
String source = null;
String external = null;
String contributed = null;
Expand All @@ -166,7 +167,7 @@ public List<String> getOnlyProjectPythonPathStr(boolean addExternal) throws Core
}

//Substitute with variables!
StringSubstitution stringSubstitution = new StringSubstitution(nature);
StringSubstitution stringSubstitution = new StringSubstitution(nature, addInterpreterInfoSubstitutions);

source = (String) getProjectSourcePath(true, stringSubstitution, RETURN_STRING_WITH_SEPARATOR);
if (addExternal) {
Expand Down Expand Up @@ -238,7 +239,7 @@ public Set<IResource> getProjectSourcePathFolderSet() throws CoreException {
}

//Substitute with variables!
StringSubstitution stringSubstitution = new StringSubstitution(nature);
StringSubstitution stringSubstitution = new StringSubstitution(nature, true);

source = (String) getProjectSourcePath(true, stringSubstitution, RETURN_STRING_WITH_SEPARATOR);

Expand Down Expand Up @@ -386,7 +387,7 @@ private Object getProjectSourcePath(boolean replace, StringSubstitution substitu
}

if (replace && substitution == null) {
substitution = new StringSubstitution(fNature);
substitution = new StringSubstitution(fNature, true);
}

//we have to validate it, because as we store the values relative to the workspace, and not to the
Expand Down Expand Up @@ -489,7 +490,7 @@ private String getProjectExternalSourcePath(boolean replace, StringSubstitution
}

if (replace && substitution == null) {
substitution = new StringSubstitution(fNature);
substitution = new StringSubstitution(fNature, true);
}
return trimAndReplaceVariablesIfNeeded(replace, extPath, nature, substitution);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,8 @@ public String getProjectExternalSourcePath(boolean replaceVariables) throws Core
}

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

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,8 @@ public interface IPythonPathNature {
* complete paths in the filesystem.
* @throws CoreException
*/
public List<String> getOnlyProjectPythonPathStr(boolean addExternal) throws CoreException;
public List<String> getOnlyProjectPythonPathStr(boolean addExternal, boolean addInterpreterInfoSubstitutions)
throws CoreException;

/**
* Sets the project source path (paths are relative to the project location and are separated by | )
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,22 +53,23 @@ public StringSubstitution(Map<String, String> vars) {
this.variableSubstitution = vars;
}

public StringSubstitution(IPythonNature nature) {
public StringSubstitution(IPythonNature nature, boolean addInterpreterInfoSubstitutions) {
if (nature != null) {
try {
IPythonPathNature pythonPathNature = nature.getPythonPathNature();
IProject project = nature.getProject(); //note: project can be null when creating a new project and receiving a system nature.
initialize(pythonPathNature, project);
initialize(pythonPathNature, project, addInterpreterInfoSubstitutions);
} catch (Exception e) {
Log.log(e);
}
}
}

public void initialize(IPythonPathNature pythonPathNature, IProject project) {
public void initialize(IPythonPathNature pythonPathNature, IProject project,
boolean addInterpreterInfoSubstitutions) {
try {
try {
variableSubstitution = pythonPathNature.getVariableSubstitution();
variableSubstitution = pythonPathNature.getVariableSubstitution(addInterpreterInfoSubstitutions);
IPathVariableManager projectPathVarManager = null;
try {
if (project != null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,8 @@ public List<String> getProjectExternalSourcePathAsList(boolean replaceVariables)
}

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

Expand Down Expand Up @@ -1104,7 +1105,7 @@ public AdditionalGrammarVersionsToCheck getAdditionalGrammarVersions() throws Mi
public Tuple<String, String> getVersionAndError(boolean translateIfInterpreter) throws CoreException {
throw new RuntimeException("Not implemented");
}
});
}, false);
return s;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -102,16 +102,14 @@ public void widgetSelected(SelectionEvent e) {
if (!fUnitTesting) {
title = "Main Module";
message = "Choose Python module which starts execution";
}
else
{
} else {
title = "Main Modules";
message = "Choose Python module(s) and/or package(s) to test";
}
PythonModulePickerDialog dialog = new PythonModulePickerDialog(lParent.getShell(), title,
message, project, fUnitTesting);

// Fixed request 1407469: main module browse button forgets path
// Fixed request 1407469: main module browse button forgets path
if (currentResources != null) {
dialog.setInitialSelections(currentResources);
}
Expand All @@ -127,8 +125,7 @@ public void widgetSelected(SelectionEvent e) {
if (results[i] instanceof IResource) {
if (results[i] instanceof IFile) {
r_results.add((IFile) results[i]);
}
else {
} else {
r_results.add((IResource) results[i]);
}
}
Expand All @@ -142,7 +139,7 @@ public void widgetSelected(SelectionEvent e) {
}
});

// Create a ModifyListener, used to listen for project modifications in the ProjectBlock.
// Create a ModifyListener, used to listen for project modifications in the ProjectBlock.
// This assumes that the Project is in a Text control...
fProjectModifyListener = new ModifyListener() {
@Override
Expand All @@ -169,7 +166,7 @@ public void modifyText(ModifyEvent e) {

/*
* (non-Javadoc)
*
*
* @see org.eclipse.debug.ui.ILaunchConfigurationTab#getName()
*/
@Override
Expand All @@ -179,7 +176,7 @@ public String getName() {

/*
* (non-Javadoc)
*
*
* @see org.eclipse.debug.ui.ILaunchConfigurationTab#initializeFrom(org.eclipse.debug.core.ILaunchConfiguration)
*/
@Override
Expand Down Expand Up @@ -234,10 +231,10 @@ public void setDefaults(ILaunchConfigurationWorkingCopy configuration) {

/**
* Obtains an IFile that targets the current main module.
*
*
* This is used for initializing the module selection dialog.
*
* @return The main module file.
*
* @return The main module file.
*/
private IResource[] getMainModuleResources() {
String path = fMainModuleText.getText();
Expand Down Expand Up @@ -303,16 +300,17 @@ public StringSubstitution getStringSubstitution(IWorkspaceRoot root) {
nature = PythonNature.getPythonNature(resource);
}

StringSubstitution stringSubstitution = new StringSubstitution(nature);
boolean addInterpreterInfoSubstitutions = true;
StringSubstitution stringSubstitution = new StringSubstitution(nature, addInterpreterInfoSubstitutions);
return stringSubstitution;
}

/**
* Sets attributes in the working copy
*
*
* @param configuration The configuration to set the attribute in
* @param name Name of the attribute to set
* @param value Value to set
* @param value Value to set
*/
private void setAttribute(ILaunchConfigurationWorkingCopy configuration, String name, String value) {
if (value == null || value.length() == 0) {
Expand Down Expand Up @@ -397,7 +395,7 @@ public boolean isValid(ILaunchConfiguration launchConfig) {
/**
* Obtain a listener, used to detect changes of the currently selected project
* This updates the browse button, and allos the appropriate selection of the main module.
*
*
* @return a ModifyListener that updates the block controls.
*/
public ModifyListener getProjectModifyListener() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ public static String getArguments(ILaunchConfiguration configuration, boolean ma
}

private static StringSubstitution getStringSubstitution(IPythonNature nature) {
return new StringSubstitution(nature);
return new StringSubstitution(nature, true);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ public void run(IAction action) {
return;
}
String javaLibs = null;
for (String path : nature.getPythonPathNature().getOnlyProjectPythonPathStr(true)) {
for (String path : nature.getPythonPathNature().getOnlyProjectPythonPathStr(true, true)) {
if (path.endsWith(".jar")) {
if (javaLibs == null) {
javaLibs = path;
Expand Down
Loading

0 comments on commit 9b27249

Please sign in to comment.