Skip to content

Commit

Permalink
Accept VM args in the python interpreter configuration and use defaul…
Browse files Browse the repository at this point in the history
…t for Python 3.11.
  • Loading branch information
fabioz committed Oct 29, 2023
1 parent acbd69d commit af194f5
Show file tree
Hide file tree
Showing 13 changed files with 242 additions and 18 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@
import org.python.pydev.shared_core.string.StringUtils;
import org.python.pydev.shared_core.structure.Tuple;
import org.python.pydev.shared_core.utils.PlatformUtils;
import org.python.pydev.shared_core.version.Version;
import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
Expand Down Expand Up @@ -251,6 +252,10 @@ public boolean equals(Object o) {
return false;
}

if (info.vmArgs.equals(this.vmArgs) == false) {
return false;
}

if (this.pipenvTargetDir != null) {
if (info.pipenvTargetDir == null) {
return false;
Expand Down Expand Up @@ -354,6 +359,7 @@ public static InterpreterInfo fromString(String received, boolean askUserInOutPa

boolean fromPythonBackend = false;
String infoExecutable = null;
String infoVmArgs = null;
String infoName = null;
String infoVersion = null;
String pipenvTargetDir = null;
Expand All @@ -380,6 +386,9 @@ public static InterpreterInfo fromString(String received, boolean askUserInOutPa
} else if ("executable".equals(name)) {
infoExecutable = data;

} else if ("vmArgs".equals(name)) {
infoVmArgs = data;

} else if ("pipenv_target_dir".equals(name)) {
pipenvTargetDir = data;

Expand Down Expand Up @@ -495,6 +504,17 @@ public static InterpreterInfo fromString(String received, boolean askUserInOutPa
new ArrayList<String>(), forcedLibs, envVars, stringSubstitutionVars);
info.setName(infoName);
info.setActivateCondaEnv(activateCondaEnv);
if (infoVmArgs != null) {
info.setVmArgs(infoVmArgs);
} else {
if (infoVersion != null) {
Version foundVersion = new Version(infoVersion);
if (foundVersion.isGreaterThanOrEqualTo(new Version("3.11"))) {
info.setVmArgs("-Xfrozen_modules=off");
}
}
}

info.pipenvTargetDir = pipenvTargetDir;
for (String s : predefinedPaths) {
info.addPredefinedCompletionsPath(s);
Expand Down Expand Up @@ -782,6 +802,11 @@ public String toString() {
buffer.append("<activate_conda>" + activateCondaEnv + "</activate_conda>\n");
}

// i.e.: We always save it, even if empty and on load we may set default values.
buffer.append("<vmArgs>");
buffer.append(escape(vmArgs));
buffer.append("</vmArgs>\n");

if (pipenvTargetDir != null) {
buffer.append("<pipenv_target_dir>");
buffer.append(escape(pipenvTargetDir));
Expand Down Expand Up @@ -2057,6 +2082,21 @@ public void removePredefinedCompletionPath(String item) {

private boolean activateCondaEnv;

private String vmArgs = "";

@Override
public void setVmArgs(String vmArgs) {
if (vmArgs == null) {
throw new NullPointerException("vmArgs may not be null");
}
this.vmArgs = vmArgs;
}

@Override
public String getVmArgs() {
return this.vmArgs;
}

private String pipenvTargetDir;

public void setLoadFinished(boolean b) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,10 @@ public UnableToFindExecutableException(String msg) {
*/
File searchExecutableForInterpreter(String executable, boolean recursive) throws UnableToFindExecutableException;

public String getVmArgs();

public void setVmArgs(String vmArgs);

public boolean getActivateCondaEnv();

void setActivateCondaEnv(boolean b);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,11 @@ public interface IInterpreterManager {
*/
public String IRONPYTHON_INTERNAL_SHELL_VM_ARGS = "IRONPYTHON_INTERNAL_SHELL_VM_ARGS";

/**
* This is the constant from where we get the default vm args for Python
*/
public String PYTHON_INTERNAL_SHELL_VM_ARGS = "PYTHON_INTERNAL_SHELL_VM_ARGS";

/**
* Constant for the default values
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ public static class Versions {
public static final String JYTHON_PREFIX = "jython";
public static final String IRONYTHON_PREFIX = "ironpython";

public static final String LATEST_VERSION_NUMBER = "3.12";

static {
ALL_PYTHON_VERSIONS.add(PYTHON_VERSION_3_0);
ALL_PYTHON_VERSIONS.add(PYTHON_VERSION_3_6);
Expand Down Expand Up @@ -169,8 +171,8 @@ public static String convertToInternalVersion(FastStringBuffer buf, final String
+ " is no longer supported.\n\nPlease refer to: Need to use older Eclipse/Java/Python\n\nin https://www.pydev.org/download.html\n\n");
}
// It seems a version we don't directly support, let's check it...
Log.log("Unsupported version:" + version + " (falling back to 3.11)");
buf.append("3.11"); // latest 3
Log.log("Unsupported version:" + version + " (falling back to " + LATEST_VERSION_NUMBER + ")");
buf.append(LATEST_VERSION_NUMBER); // latest 3
String fullVersion = buf.toString();
if (ALL_VERSIONS_ANY_FLAVOR.contains(fullVersion)) {
return fullVersion;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
Expand Down Expand Up @@ -95,7 +96,7 @@ public class PythonRunnerConfig {
public final IProject project;
public final IPath[] resource;
public final IPath interpreter;
public final IInterpreterInfo interpreterLocation;
public final IInterpreterInfo interpreterInfo;
private final String arguments;
public final File workingDirectory;
public final String pythonpathUsed;
Expand Down Expand Up @@ -399,8 +400,8 @@ public PythonRunnerConfig(ILaunchConfiguration conf, String mode, String run,
acceptTimeout = PydevPrefs.getEclipsePreferences().getInt(PyDevEditorPreferences.CONNECT_TIMEOUT,
PyDevEditorPreferences.DEFAULT_CONNECT_TIMEOUT);

interpreterLocation = getInterpreterLocation(conf, pythonNature, this.getRelatedInterpreterManager());
interpreter = getInterpreter(interpreterLocation, conf, pythonNature);
interpreterInfo = getInterpreterLocation(conf, pythonNature, this.getRelatedInterpreterManager());
interpreter = getInterpreter(interpreterInfo, conf, pythonNature);

//make the environment
ILaunchManager launchManager = DebugPlugin.getDefault().getLaunchManager();
Expand All @@ -418,14 +419,14 @@ public PythonRunnerConfig(ILaunchConfiguration conf, String mode, String run,

if (envp == null) {
//ok, the user has done nothing to the environment, just get all the default environment which has the pythonpath in it
envp = SimpleRunner.getEnvironment(pythonNature, interpreterLocation, manager);
envp = SimpleRunner.getEnvironment(pythonNature, interpreterInfo, manager);

} else {
//ok, the user has done something to configure it, so, just add the pythonpath to the
//current env (if he still didn't do so)
Map envMap = conf.getAttribute(ILaunchManager.ATTR_ENVIRONMENT_VARIABLES, (Map) null);

String pythonpath = SimpleRunner.makePythonPathEnvString(pythonNature, interpreterLocation, manager);
String pythonpath = SimpleRunner.makePythonPathEnvString(pythonNature, interpreterInfo, manager);
updateVar(pythonNature, manager, win32, envMap, "PYTHONPATH", pythonpath);
if (isJython()) {
//Also update the classpath env variable.
Expand All @@ -440,7 +441,7 @@ public PythonRunnerConfig(ILaunchConfiguration conf, String mode, String run,
}

//And we also must get the environment variables specified in the interpreter manager.
envp = interpreterLocation.updateEnv(envp, envMap.keySet());
envp = interpreterInfo.updateEnv(envp, envMap.keySet());
}

boolean hasDjangoNature = project.hasNature(PythonNature.DJANGO_NATURE_ID);
Expand Down Expand Up @@ -1011,33 +1012,40 @@ private void addDebugArgs(List<String> cmdArgs, String vmType, boolean actualRun
}
}

/**
* @param cmdArgs
* @throws CoreException
*/
private void addVmArgs(List<String> cmdArgs) throws CoreException {
String[] vmArguments = getVMArguments(configuration);
if (vmArguments != null) {
String[] vmArguments = getLaunchVMArguments(configuration);
if (vmArguments != null && vmArguments.length > 0) {
for (int i = 0; i < vmArguments.length; i++) {
cmdArgs.add(vmArguments[i]);
}
} else {
// Use default VM arguments from the interpreter.
String vmArgs = interpreterInfo.getVmArgs();
if (vmArgs != null && vmArgs.length() > 0) {
String[] parsed = parseVmArguments(vmArgs);
cmdArgs.addAll(Arrays.asList(parsed));
}
}
}

/**
* @return an array with the vm arguments in the given configuration.
* @throws CoreException
*/
private String[] getVMArguments(ILaunchConfiguration configuration) throws CoreException {
private String[] getLaunchVMArguments(ILaunchConfiguration configuration) throws CoreException {
String args = configuration.getAttribute(Constants.ATTR_VM_ARGUMENTS, (String) null);
if (args != null && args.trim().length() > 0) {
String expanded = getStringSubstitution(PythonNature.getPythonNature(project)).performStringSubstitution(
args);
return ProcessUtils.parseArguments(expanded);
return parseVmArguments(args);
}
return null;
}

private String[] parseVmArguments(String args) throws CoreException {
String expanded = getStringSubstitution(PythonNature.getPythonNature(project)).performStringSubstitution(
args);
return ProcessUtils.parseArguments(expanded);
}

/**
* @return A command line to be shown to the user. Note that this command line should not actually be used for
* an execution (only String[] should be passed to Runtie.exec)
Expand Down
1 change: 1 addition & 0 deletions plugins/org.python.pydev.shared_core/META-INF/MANIFEST.MF
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,7 @@ Export-Package: org.apache.lucene,
org.python.pydev.shared_core.testutils,
org.python.pydev.shared_core.threaded_objects_pool,
org.python.pydev.shared_core.utils,
org.python.pydev.shared_core.version,
org.python.pydev.shared_core.yaml
Bundle-Vendor: Brainwy Software Ltda
Bundle-RequiredExecutionEnvironment: JavaSE-17
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package org.python.pydev.shared_core.version;

import java.util.StringTokenizer;

public class Version implements Comparable<Version> {
private int major;
private int minor;
private int patch;

public Version(String versionString) {
StringTokenizer tokenizer = new StringTokenizer(versionString, ".");
if (tokenizer.hasMoreTokens()) {
major = Integer.parseInt(tokenizer.nextToken());
}
if (tokenizer.hasMoreTokens()) {
minor = Integer.parseInt(tokenizer.nextToken());
}
if (tokenizer.hasMoreTokens()) {
patch = Integer.parseInt(tokenizer.nextToken());
}
}

@Override
public int compareTo(Version other) {
if (this.major != other.major) {
return Integer.compare(this.major, other.major);
}
if (this.minor != other.minor) {
return Integer.compare(this.minor, other.minor);
}
return Integer.compare(this.patch, other.patch);
}

public boolean isGreaterThanOrEqualTo(Version other) {
return compareTo(other) >= 0;
}

@Override
public String toString() {
return major + "." + minor + "." + patch;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package org.python.pydev.shared_core.version;

import junit.framework.TestCase;

public class VersionTest extends TestCase {

public void testVersionComparison() {
Version v1 = new Version("1.2");
Version v2 = new Version("1.2.1");
Version v3 = new Version("1.2.2");
Version v4 = new Version("1.3");

Version v5 = new Version("2.0");
Version v6 = new Version("2.0.0");

assertTrue(v1.isGreaterThanOrEqualTo(v1));
assertTrue(v5.isGreaterThanOrEqualTo(v6));
assertTrue(v5.isGreaterThanOrEqualTo(v4));

assertFalse(v1.isGreaterThanOrEqualTo(v2));
assertFalse(v2.isGreaterThanOrEqualTo(v3));
assertFalse(v3.isGreaterThanOrEqualTo(v4));
assertFalse(v4.isGreaterThanOrEqualTo(v5));
}

public static void main(String[] args) {
junit.textui.TestRunner.run(VersionTest.class);
}
}
Loading

0 comments on commit af194f5

Please sign in to comment.