/** * Copyright (c) 2005-2011 by Appcelerator, Inc. All Rights Reserved. * Licensed under the terms of the Eclipse Public License (EPL). * Please see the license.txt included with this distribution for details. * Any modifications to this file must keep this entire header intact. */ /* * Created on May 11, 2005 * * @author Fabio Zadrozny */ package org.python.pydev.ui.pythonpathconf; import java.io.ByteArrayInputStream; import java.io.File; import java.io.FilenameFilter; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Properties; import java.util.Set; import java.util.TreeSet; import java.util.zip.ZipFile; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.SafeRunner; import org.eclipse.core.variables.IStringVariableManager; import org.eclipse.core.variables.VariablesPlugin; import org.eclipse.jface.util.SafeRunnable; import org.eclipse.swt.SWT; import org.eclipse.swt.widgets.MessageBox; import org.python.pydev.core.ExtensionHelper; import org.python.pydev.core.IInterpreterInfo; import org.python.pydev.core.IInterpreterManager; import org.python.pydev.core.ISystemModulesManager; import org.python.pydev.core.PropertiesHelper; import org.python.pydev.core.docutils.StringUtils; import org.python.pydev.core.log.Log; import org.python.pydev.editor.actions.PyAction; import org.python.pydev.editor.codecompletion.revisited.ProjectModulesManager; import org.python.pydev.editor.codecompletion.revisited.SystemModulesManager; import org.python.pydev.plugin.nature.PythonNature; import org.python.pydev.ui.pythonpathconf.AbstractInterpreterEditor.CancelException; import org.w3c.dom.Document; import org.w3c.dom.NamedNodeMap; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import com.aptana.shared_core.callbacks.ICallback; import com.aptana.shared_core.string.FastStringBuffer; import com.aptana.shared_core.structure.Tuple; import com.aptana.shared_core.utils.PlatformUtils; import com.aptana.shared_core.utils.RunInUiThread; public class InterpreterInfo implements IInterpreterInfo { //We want to force some libraries to be analyzed as source (e.g.: django) private static String[] LIBRARIES_TO_IGNORE_AS_FORCED_BUILTINS = new String[] { "django" }; /** * For jython, this is the jython.jar * * For python, this is the path to the python executable */ public volatile String executableOrJar; public String getExecutableOrJar() { return executableOrJar; } /** * Folders or zip files: they should be passed to the pythonpath */ public final java.util.List<String> libs = new ArrayList<String>(); /** * __builtin__, os, math, etc for python * * check sys.builtin_module_names and others that should * be forced to use code completion as builtins, such os, math, etc. */ private final Set<String> forcedLibs = new TreeSet<String>(); /** * This is the cache for the builtins (that's the same thing as the forcedLibs, but in a different format, * so, whenever the forcedLibs change, this should be changed too). */ private String[] builtinsCache; private Map<String, File> predefinedBuiltinsCache; /** * module management for the system is always binded to an interpreter (binded in this class) * * The modules manager is no longer persisted. It is restored from a separate file, because we do * not want to keep it in the 'configuration', as a giant Base64 string. */ private final ISystemModulesManager modulesManager; /** * This callback is only used in tests, to configure the paths that should be chosen after the interpreter is selected. */ public static ICallback<Boolean, Tuple<List<String>, List<String>>> configurePathsCallback = null; /** * This is the version for the python interpreter (it is regarded as a String with Major and Minor version * for python in the format '2.5' or '2.4'. */ private final String version; /** * This are the environment variables that should be used when this interpreter is specified. * May be null if no env. variables are specified. */ private String[] envVariables; private Properties stringSubstitutionVariables; private final Set<String> predefinedCompletionsPath = new TreeSet<String>(); /** * This is the way that the interpreter should be referred. Can be null (in which case the executable is * used as the name) */ private String name; public ISystemModulesManager getModulesManager() { return modulesManager; } /** * Variables manager to resolve variables in the interpreters environment. * initStringVariableManager() creates an appropriate version when running * within Eclipse, for test the stringVariableManagerForTests can be set to * an appropriate mock object */ /*default*/IStringVariableManager stringVariableManagerForTests; private IStringVariableManager getStringVariableManager() { if (stringVariableManagerForTests != null) { return stringVariableManagerForTests; } VariablesPlugin variablesPlugin = VariablesPlugin.getDefault(); if (variablesPlugin != null) { return variablesPlugin.getStringVariableManager(); } return null; } /** * @return the pythonpath to be used (only the folders) */ public List<String> getPythonPath() { return new ArrayList<String>(libs); } public InterpreterInfo(String version, String exe, Collection<String> libs0) { this.executableOrJar = exe; this.version = version; ISystemModulesManager modulesManager = new SystemModulesManager(this); this.modulesManager = modulesManager; libs.addAll(libs0); } /*default*/InterpreterInfo(String version, String exe, Collection<String> libs0, Collection<String> dlls) { this(version, exe, libs0); } /*default*/InterpreterInfo(String version, String exe, List<String> libs0, List<String> dlls, List<String> forced) { this(version, exe, libs0, dlls, forced, null, null); } /** * Note: dlls is no longer used! */ /*default*/InterpreterInfo(String version, String exe, List<String> libs0, List<String> dlls, List<String> forced, List<String> envVars, Properties stringSubstitution) { this(version, exe, libs0, dlls); for (String s : forced) { if (!isForcedLibToIgnore(s)) { forcedLibs.add(s); } } if (envVars == null) { this.setEnvVariables(null); } else { this.setEnvVariables(envVars.toArray(new String[envVars.size()])); } this.setStringSubstitutionVariables(stringSubstitution); this.clearBuiltinsCache(); //force cache recreation } /** * @see java.lang.Object#equals(java.lang.Object) */ public boolean equals(Object o) { if (!(o instanceof InterpreterInfo)) { return false; } InterpreterInfo info = (InterpreterInfo) o; if (info.executableOrJar.equals(this.executableOrJar) == false) { return false; } if (info.libs.equals(this.libs) == false) { return false; } if (info.forcedLibs.equals(this.forcedLibs) == false) { return false; } if (info.predefinedCompletionsPath.equals(this.predefinedCompletionsPath) == false) { return false; } if (this.envVariables != null) { if (info.envVariables == null) { return false; } //both not null if (!Arrays.equals(this.envVariables, info.envVariables)) { return false; } } else { //env is null -- the other must be too if (info.envVariables != null) { return false; } } //Consider null stringSubstitutionVariables equal to empty stringSubstitutionVariables. if (this.stringSubstitutionVariables != null) { if (info.stringSubstitutionVariables == null) { if (this.stringSubstitutionVariables.size() != 0) { return false; } } else { //both not null if (!this.stringSubstitutionVariables.equals(info.stringSubstitutionVariables)) { return false; } } } else { //ours is null -- the other must be too if (info.stringSubstitutionVariables != null && info.stringSubstitutionVariables.size() > 0) { return false; } } return true; } public int hashCode() { assert false : "hashCode not designed"; return 42; // any arbitrary constant will do } /** * * @param received * String to parse * @param askUserInOutPath * true to prompt user about which paths to include. When the * user is prompted, IInterpreterNewCustomEntries extension will * be run to contribute additional entries * @return new interpreter info */ public static InterpreterInfo fromString(String received, boolean askUserInOutPath) { if (received.toLowerCase().indexOf("executable") == -1) { throw new RuntimeException( "Unable to recreate the Interpreter info (Its format changed. Please, re-create your Interpreter information).Contents found:" + received); } received = received.trim(); if (!received.startsWith("<xml>")) { return fromStringOld(received, askUserInOutPath); } else { DocumentBuilder parser; try { parser = DocumentBuilderFactory.newInstance().newDocumentBuilder(); Document document = parser.parse(new ByteArrayInputStream(received.getBytes())); NodeList childNodes = document.getChildNodes(); for (int i = 0; i < childNodes.getLength(); i++) { Node item = childNodes.item(i); String nodeName = item.getNodeName(); if (!("xml".equals(nodeName))) { continue; } NodeList xmlNodes = item.getChildNodes(); String infoExecutable = null; String infoName = null; String infoVersion = null; List<String> selection = new ArrayList<String>(); List<String> toAsk = new ArrayList<String>(); List<String> forcedLibs = new ArrayList<String>(); List<String> envVars = new ArrayList<String>(); List<String> predefinedPaths = new ArrayList<String>(); Properties stringSubstitutionVars = new Properties(); for (int j = 0; j < xmlNodes.getLength(); j++) { Node xmlChild = xmlNodes.item(j); String name = xmlChild.getNodeName(); if ("version".equals(name)) { infoVersion = xmlChild.getTextContent().trim(); } else if ("name".equals(name)) { infoName = xmlChild.getTextContent().trim(); } else if ("executable".equals(name)) { infoExecutable = xmlChild.getTextContent().trim(); } else if ("lib".equals(name)) { NamedNodeMap attributes = xmlChild.getAttributes(); Node namedItem = attributes.getNamedItem("path"); if (namedItem != null) { String content = namedItem.getTextContent().trim(); if (content.equals("ins")) { if (askUserInOutPath) { toAsk.add(xmlChild.getTextContent().trim()); selection.add(xmlChild.getTextContent().trim()); } else { //If not asked, included by default selection.add(xmlChild.getTextContent().trim()); } } else if (content.equals("out")) { if (askUserInOutPath) { toAsk.add(xmlChild.getTextContent().trim()); } else { //If not asked, included by default selection.add(xmlChild.getTextContent().trim()); } } else { //Not 'ins' nor 'out'? Let's warn and add it... Log.log("Unexpected 'path' attribute in xml: " + content); selection.add(xmlChild.getTextContent().trim()); } } else { //If not specified, included by default selection.add(xmlChild.getTextContent().trim()); } } else if ("forced_lib".equals(name)) { forcedLibs.add(xmlChild.getTextContent().trim()); } else if ("env_var".equals(name)) { envVars.add(xmlChild.getTextContent().trim()); } else if ("string_substitution_var".equals(name)) { NodeList stringSubstitutionVarNode = xmlChild.getChildNodes(); Node keyNode = getNode(stringSubstitutionVarNode, "key"); Node valueNode = getNode(stringSubstitutionVarNode, "value"); stringSubstitutionVars.put(keyNode.getTextContent().trim(), valueNode.getTextContent() .trim()); } else if ("predefined_completion_path".equals(name)) { predefinedPaths.add(xmlChild.getTextContent().trim()); } else if ("#text".equals(name)) { if (xmlChild.getTextContent().trim().length() > 0) { throw new RuntimeException("Unexpected text content: " + xmlChild.getTextContent()); } } else { throw new RuntimeException("Unexpected node: " + name + " Text content: " + xmlChild.getTextContent()); } } if (askUserInOutPath) { AdditionalEntries additionalEntries = new AdditionalEntries(); Collection<String> additionalLibraries = additionalEntries.getAdditionalLibraries(); addUnique(toAsk, additionalLibraries); addUnique(selection, additionalLibraries); addUnique(forcedLibs, additionalEntries.getAdditionalBuiltins()); //Load environment variables Map<String, String> existingEnv = new HashMap<String, String>(); Collection<String> additionalEnvVariables = additionalEntries.getAdditionalEnvVariables(); for (String var : additionalEnvVariables) { Tuple<String, String> sp = StringUtils.splitOnFirst(var, '='); existingEnv.put(sp.o1, sp.o2); } for (String var : envVars) { Tuple<String, String> sp = StringUtils.splitOnFirst(var, '='); existingEnv.put(sp.o1, sp.o2); } envVars.clear(); Set<Entry<String, String>> set = existingEnv.entrySet(); for (Entry<String, String> entry : set) { envVars.add(entry.getKey() + "=" + entry.getValue()); } //Additional string substitution variables Map<String, String> additionalStringSubstitutionVariables = additionalEntries .getAdditionalStringSubstitutionVariables(); Set<Entry<String, String>> entrySet = additionalStringSubstitutionVariables.entrySet(); for (Entry<String, String> entry : entrySet) { if (!stringSubstitutionVars.containsKey(entry.getKey())) { stringSubstitutionVars.setProperty(entry.getKey(), entry.getValue()); } } } try { selection = filterUserSelection(selection, toAsk); } catch (CancelException e) { return null; } InterpreterInfo info = new InterpreterInfo(infoVersion, infoExecutable, selection, new ArrayList<String>(), forcedLibs, envVars, stringSubstitutionVars); info.setName(infoName); for (String s : predefinedPaths) { info.addPredefinedCompletionsPath(s); } return info; } throw new RuntimeException("Could not find 'xml' node as root of the document."); } catch (Exception e) { throw new RuntimeException(e); //What can we do about that? } } } /** * Add additions that are not already in col */ private static void addUnique(Collection<String> col, Collection<String> additions) { for (String string : additions) { if (!col.contains(string)) { col.add(string); } } } /** * Implementation of extension point to get all additions. */ private static class AdditionalEntries implements IInterpreterNewCustomEntries { private final List<IInterpreterNewCustomEntries> fParticipants; @SuppressWarnings("unchecked") AdditionalEntries() { fParticipants = ExtensionHelper.getParticipants(ExtensionHelper.PYDEV_INTERPRETER_NEW_CUSTOM_ENTRIES); } public Collection<String> getAdditionalLibraries() { final Collection<String> additions = new ArrayList<String>(); for (final IInterpreterNewCustomEntries newEntriesProvider : fParticipants) { SafeRunner.run(new SafeRunnable() { public void run() { additions.addAll(newEntriesProvider.getAdditionalLibraries()); } }); } return additions; } public Collection<String> getAdditionalEnvVariables() { final Collection<String> additions = new ArrayList<String>(); for (final IInterpreterNewCustomEntries newEntriesProvider : fParticipants) { SafeRunner.run(new SafeRunnable() { public void run() { additions.addAll(newEntriesProvider.getAdditionalEnvVariables()); } }); } return additions; } public Collection<String> getAdditionalBuiltins() { final Collection<String> additions = new ArrayList<String>(); for (final IInterpreterNewCustomEntries newEntriesProvider : fParticipants) { SafeRunner.run(new SafeRunnable() { public void run() { additions.addAll(newEntriesProvider.getAdditionalBuiltins()); } }); } return additions; } public Map<String, String> getAdditionalStringSubstitutionVariables() { final Map<String, String> additions = new HashMap<String, String>(); for (final IInterpreterNewCustomEntries newEntriesProvider : fParticipants) { SafeRunner.run(new SafeRunnable() { public void run() { additions.putAll(newEntriesProvider.getAdditionalStringSubstitutionVariables()); } }); } return additions; } } private static Node getNode(NodeList nodeList, String string) { for (int i = 0; i < nodeList.getLength(); i++) { Node item = nodeList.item(i); if (string.equals(item.getNodeName())) { return item; } } throw new RuntimeException("Unable to find node: " + string); } /** * Format we receive should be: * * Executable:python.exe|lib1|lib2|lib3@dll1|dll2|dll3$forcedBuitin1|forcedBuiltin2^envVar1|envVar2@PYDEV_STRING_SUBST_VARS@PropertiesObjectAsString * * or * * Version2.5Executable:python.exe|lib1|lib2|lib3@dll1|dll2|dll3$forcedBuitin1|forcedBuiltin2^envVar1|envVar2@PYDEV_STRING_SUBST_VARS@PropertiesObjectAsString * (added only when version 2.5 was added, so, if the string does not have it, it is regarded as 2.4) * * or * * Name:MyInterpreter:EndName:Version2.5Executable:python.exe|lib1|lib2|lib3@dll1|dll2|dll3$forcedBuitin1|forcedBuiltin2^envVar1|envVar2@PYDEV_STRING_SUBST_VARS@PropertiesObjectAsString * * Symbols ': @ $' */ private static InterpreterInfo fromStringOld(String received, boolean askUserInOutPath) { Tuple<String, String> predefCompsPath = StringUtils.splitOnFirst(received, "@PYDEV_PREDEF_COMPS_PATHS@"); received = predefCompsPath.o1; //Note that the new lines are important for the string substitution, so, we must remove it before removing new lines Tuple<String, String> stringSubstitutionVarsSplit = StringUtils.splitOnFirst(received, "@PYDEV_STRING_SUBST_VARS@"); received = stringSubstitutionVarsSplit.o1; received = received.replaceAll("\n", "").replaceAll("\r", ""); String name = null; if (received.startsWith("Name:")) { int endNameIndex = received.indexOf(":EndName:"); if (endNameIndex != -1) { name = received.substring("Name:".length(), endNameIndex); received = received.substring(endNameIndex + ":EndName:".length()); } } Tuple<String, String> envVarsSplit = StringUtils.splitOnFirst(received, '^'); Tuple<String, String> forcedSplit = StringUtils.splitOnFirst(envVarsSplit.o1, '$'); Tuple<String, String> libsSplit = StringUtils.splitOnFirst(forcedSplit.o1, '@'); String exeAndLibs = libsSplit.o1; String version = "2.4"; //if not found in the string, the grammar version is regarded as 2.4 String[] exeAndLibs1 = exeAndLibs.split("\\|"); String exeAndVersion = exeAndLibs1[0]; String lowerExeAndVersion = exeAndVersion.toLowerCase(); if (lowerExeAndVersion.startsWith("version")) { int execut = lowerExeAndVersion.indexOf("executable"); version = exeAndVersion.substring(0, execut).substring(7); exeAndVersion = exeAndVersion.substring(7 + version.length()); } String executable = exeAndVersion.substring(exeAndVersion.indexOf(":") + 1, exeAndVersion.length()); List<String> selection = new ArrayList<String>(); List<String> toAsk = new ArrayList<String>(); for (int i = 1; i < exeAndLibs1.length; i++) { //start at 1 (0 is exe) String trimmed = exeAndLibs1[i].trim(); if (trimmed.length() > 0) { if (trimmed.endsWith("OUT_PATH")) { trimmed = trimmed.substring(0, trimmed.length() - 8); if (askUserInOutPath) { toAsk.add(trimmed); } else { //Change 2.0.1: if not asked, it's included by default! selection.add(trimmed); } } else if (trimmed.endsWith("INS_PATH")) { trimmed = trimmed.substring(0, trimmed.length() - 8); if (askUserInOutPath) { toAsk.add(trimmed); selection.add(trimmed); } else { selection.add(trimmed); } } else { selection.add(trimmed); } } } try { selection = filterUserSelection(selection, toAsk); } catch (CancelException e) { return null; } ArrayList<String> l1 = new ArrayList<String>(); if (libsSplit.o2.length() > 1) { fillList(libsSplit, l1); } ArrayList<String> l2 = new ArrayList<String>(); if (forcedSplit.o2.length() > 1) { fillList(forcedSplit, l2); } ArrayList<String> l3 = new ArrayList<String>(); if (envVarsSplit.o2.length() > 1) { fillList(envVarsSplit, l3); } Properties p4 = null; if (stringSubstitutionVarsSplit.o2.length() > 1) { p4 = PropertiesHelper.createPropertiesFromString(stringSubstitutionVarsSplit.o2); } InterpreterInfo info = new InterpreterInfo(version, executable, selection, l1, l2, l3, p4); if (predefCompsPath.o2.length() > 1) { List<String> split = StringUtils.split(predefCompsPath.o2, '|'); for (String s : split) { s = s.trim(); if (s.length() > 0) { info.addPredefinedCompletionsPath(s); } } } info.setName(name); return info; } public static List<String> filterUserSelection(List<String> selection, List<String> toAsk) throws CancelException { boolean result = true;//true == OK, false == CANCELLED if (ProjectModulesManager.IN_TESTS) { if (InterpreterInfo.configurePathsCallback != null) { InterpreterInfo.configurePathsCallback.call(new Tuple<List<String>, List<String>>(toAsk, selection)); } } else { if (toAsk.size() > 0) { PythonSelectionLibrariesDialog runnable = new PythonSelectionLibrariesDialog(selection, toAsk, true); try { RunInUiThread.sync(runnable); } catch (NoClassDefFoundError e) { } catch (UnsatisfiedLinkError e) { //this means that we're running unit-tests, so, we don't have to do anything about it //as 'l' is already ok. } result = runnable.getOkResult(); if (result == false) { //Canceled by the user throw new CancelException(); } selection = runnable.getSelection(); } } return selection; } private static void fillList(Tuple<String, String> forcedSplit, ArrayList<String> l2) { String forcedLibs = forcedSplit.o2; for (String trimmed : StringUtils.splitAndRemoveEmptyTrimmed(forcedLibs, '|')) { trimmed = trimmed.trim(); if (trimmed.length() > 0) { l2.add(trimmed); } } } /** * @see java.lang.Object#toString() */ public String toString() { FastStringBuffer buffer = new FastStringBuffer(); buffer.append("<xml>\n"); if (this.name != null) { buffer.append("<name>"); buffer.append(this.name); buffer.append("</name>\n"); } buffer.append("<version>"); buffer.append(version); buffer.append("</version>\n"); buffer.append("<executable>"); buffer.append(executableOrJar); buffer.append("</executable>\n"); for (Iterator<String> iter = libs.iterator(); iter.hasNext();) { buffer.append("<lib>"); buffer.append(iter.next().toString()); buffer.append("</lib>\n"); } if (forcedLibs.size() > 0) { for (Iterator<String> iter = forcedLibs.iterator(); iter.hasNext();) { buffer.append("<forced_lib>"); buffer.append(iter.next().toString()); buffer.append("</forced_lib>\n"); } } if (this.envVariables != null) { for (String s : envVariables) { buffer.append("<env_var>"); buffer.append(s); buffer.append("</env_var>\n"); } } if (this.stringSubstitutionVariables != null && this.stringSubstitutionVariables.size() > 0) { Set<Entry<Object, Object>> entrySet = this.stringSubstitutionVariables.entrySet(); for (Entry<Object, Object> entry : entrySet) { buffer.append("<string_substitution_var>"); buffer.append("<key>"); buffer.appendObject(entry.getKey()); buffer.append("</key>"); buffer.append("<value>"); buffer.appendObject(entry.getValue()); buffer.append("</value>"); buffer.append("</string_substitution_var>\n"); } } if (this.predefinedCompletionsPath.size() > 0) { for (String s : this.predefinedCompletionsPath) { buffer.append("<predefined_completion_path>"); buffer.append(s); buffer.append("</predefined_completion_path>"); } } buffer.append("</xml>"); return buffer.toString(); } /** * Old implementation. Kept only for testing backward compatibility! */ public String toStringOld() { FastStringBuffer buffer = new FastStringBuffer(); if (this.name != null) { buffer.append("Name:"); buffer.append(this.name); buffer.append(":EndName:"); } buffer.append("Version"); buffer.append(version); buffer.append("Executable:"); buffer.append(executableOrJar); for (Iterator<String> iter = libs.iterator(); iter.hasNext();) { buffer.append("|"); buffer.append(iter.next().toString()); } buffer.append("@"); buffer.append("$"); if (forcedLibs.size() > 0) { for (Iterator<String> iter = forcedLibs.iterator(); iter.hasNext();) { buffer.append("|"); buffer.append(iter.next().toString()); } } if (this.envVariables != null) { buffer.append("^"); for (String s : envVariables) { buffer.append(s); buffer.append("|"); } } if (this.stringSubstitutionVariables != null && this.stringSubstitutionVariables.size() > 0) { buffer.append("@PYDEV_STRING_SUBST_VARS@"); buffer.append(PropertiesHelper.createStringFromProperties(this.stringSubstitutionVariables)); } if (this.predefinedCompletionsPath.size() > 0) { buffer.append("@PYDEV_PREDEF_COMPS_PATHS@"); for (String s : this.predefinedCompletionsPath) { buffer.append("|"); buffer.append(s); } } return buffer.toString(); } /** * Adds the compiled libs (dlls) */ public void restoreCompiledLibs(IProgressMonitor monitor) { //the compiled with the interpreter should be already gotten. for (String lib : this.libs) { addForcedLibsFor(lib); } //we have it in source, but want to interpret it, source info (ast) does not give us much forcedLibs.add("os"); //we also need to add this submodule (because even though it's documented as such, it's not really //implemented that way with a separate file -- there's black magic to put it there) forcedLibs.add("os.path"); //as it is a set, there is no problem to add it twice if (this.version.startsWith("2") || this.version.startsWith("1")) { //don't add it for 3.0 onwards. forcedLibs.add("__builtin__"); //jython bug: __builtin__ is not added } forcedLibs.add("sys"); //jython bug: sys is not added forcedLibs.add("email"); //email has some lazy imports that pydev cannot handle through the source forcedLibs.add("hashlib"); //depending on the Python version, hashlib cannot find md5, so, let's always leave it there. forcedLibs.add("pytest"); //yeap, pytest does have a structure that's pretty hard to analyze. int interpreterType = getInterpreterType(); switch (interpreterType) { case IInterpreterManager.INTERPRETER_TYPE_JYTHON: //by default, we don't want to force anything to python. forcedLibs.add("StringIO"); //jython bug: StringIO is not added forcedLibs.add("re"); //re is very strange in Jython (while it's OK in Python) forcedLibs.add("com.ziclix.python.sql"); //bultin to jython but not reported. break; case IInterpreterManager.INTERPRETER_TYPE_PYTHON: //those are sources, but we want to get runtime info on them. forcedLibs.add("OpenGL"); forcedLibs.add("wxPython"); forcedLibs.add("wx"); forcedLibs.add("numpy"); forcedLibs.add("scipy"); forcedLibs.add("Image"); //for PIL //these are the builtins -- apparently sys.builtin_module_names is not ok in linux. forcedLibs.add("_ast"); forcedLibs.add("_bisect"); forcedLibs.add("_bytesio"); forcedLibs.add("_codecs"); forcedLibs.add("_codecs_cn"); forcedLibs.add("_codecs_hk"); forcedLibs.add("_codecs_iso2022"); forcedLibs.add("_codecs_jp"); forcedLibs.add("_codecs_kr"); forcedLibs.add("_codecs_tw"); forcedLibs.add("_collections"); forcedLibs.add("_csv"); forcedLibs.add("_fileio"); forcedLibs.add("_functools"); forcedLibs.add("_heapq"); forcedLibs.add("_hotshot"); forcedLibs.add("_json"); forcedLibs.add("_locale"); forcedLibs.add("_lsprof"); forcedLibs.add("_md5"); forcedLibs.add("_multibytecodec"); forcedLibs.add("_random"); forcedLibs.add("_sha"); forcedLibs.add("_sha256"); forcedLibs.add("_sha512"); forcedLibs.add("_sre"); forcedLibs.add("_struct"); forcedLibs.add("_subprocess"); forcedLibs.add("_symtable"); forcedLibs.add("_warnings"); forcedLibs.add("_weakref"); forcedLibs.add("_winreg"); forcedLibs.add("array"); forcedLibs.add("audioop"); forcedLibs.add("binascii"); forcedLibs.add("cPickle"); forcedLibs.add("cStringIO"); forcedLibs.add("cmath"); forcedLibs.add("datetime"); forcedLibs.add("errno"); forcedLibs.add("exceptions"); forcedLibs.add("future_builtins"); forcedLibs.add("gc"); forcedLibs.add("imageop"); forcedLibs.add("imp"); forcedLibs.add("itertools"); forcedLibs.add("marshal"); forcedLibs.add("math"); forcedLibs.add("mmap"); forcedLibs.add("msvcrt"); forcedLibs.add("nt"); forcedLibs.add("operator"); forcedLibs.add("parser"); forcedLibs.add("signal"); forcedLibs.add("socket"); //socket seems to have issues on linux forcedLibs.add("strop"); forcedLibs.add("sys"); forcedLibs.add("thread"); forcedLibs.add("time"); forcedLibs.add("xxsubtype"); forcedLibs.add("zipimport"); forcedLibs.add("zlib"); break; case IInterpreterManager.INTERPRETER_TYPE_IRONPYTHON: //base namespaces forcedLibs.add("System"); forcedLibs.add("Microsoft"); forcedLibs.add("clr"); //other namespaces (from http://msdn.microsoft.com/en-us/library/ms229335.aspx) forcedLibs.add("IEHost.Execute"); forcedLibs.add("Microsoft.Aspnet.Snapin"); forcedLibs.add("Microsoft.Build.BuildEngine"); forcedLibs.add("Microsoft.Build.Conversion"); forcedLibs.add("Microsoft.Build.Framework"); forcedLibs.add("Microsoft.Build.Tasks"); forcedLibs.add("Microsoft.Build.Tasks.Deployment.Bootstrapper"); forcedLibs.add("Microsoft.Build.Tasks.Deployment.ManifestUtilities"); forcedLibs.add("Microsoft.Build.Tasks.Hosting"); forcedLibs.add("Microsoft.Build.Tasks.Windows"); forcedLibs.add("Microsoft.Build.Utilities"); forcedLibs.add("Microsoft.CLRAdmin"); forcedLibs.add("Microsoft.CSharp"); forcedLibs.add("Microsoft.Data.Entity.Build.Tasks"); forcedLibs.add("Microsoft.IE"); forcedLibs.add("Microsoft.Ink"); forcedLibs.add("Microsoft.Ink.TextInput"); forcedLibs.add("Microsoft.JScript"); forcedLibs.add("Microsoft.JScript.Vsa"); forcedLibs.add("Microsoft.ManagementConsole"); forcedLibs.add("Microsoft.ManagementConsole.Advanced"); forcedLibs.add("Microsoft.ManagementConsole.Internal"); forcedLibs.add("Microsoft.ServiceModel.Channels.Mail"); forcedLibs.add("Microsoft.ServiceModel.Channels.Mail.ExchangeWebService"); forcedLibs.add("Microsoft.ServiceModel.Channels.Mail.ExchangeWebService.Exchange2007"); forcedLibs.add("Microsoft.ServiceModel.Channels.Mail.WindowsMobile"); forcedLibs.add("Microsoft.SqlServer.Server"); forcedLibs.add("Microsoft.StylusInput"); forcedLibs.add("Microsoft.StylusInput.PluginData"); forcedLibs.add("Microsoft.VisualBasic"); forcedLibs.add("Microsoft.VisualBasic.ApplicationServices"); forcedLibs.add("Microsoft.VisualBasic.Compatibility.VB6"); forcedLibs.add("Microsoft.VisualBasic.CompilerServices"); forcedLibs.add("Microsoft.VisualBasic.Devices"); forcedLibs.add("Microsoft.VisualBasic.FileIO"); forcedLibs.add("Microsoft.VisualBasic.Logging"); forcedLibs.add("Microsoft.VisualBasic.MyServices"); forcedLibs.add("Microsoft.VisualBasic.MyServices.Internal"); forcedLibs.add("Microsoft.VisualBasic.Vsa"); forcedLibs.add("Microsoft.VisualC"); forcedLibs.add("Microsoft.VisualC.StlClr"); forcedLibs.add("Microsoft.VisualC.StlClr.Generic"); forcedLibs.add("Microsoft.Vsa"); forcedLibs.add("Microsoft.Vsa.Vb.CodeDOM"); forcedLibs.add("Microsoft.Win32"); forcedLibs.add("Microsoft.Win32.SafeHandles"); forcedLibs.add("Microsoft.Windows.Themes"); forcedLibs.add("Microsoft.WindowsCE.Forms"); forcedLibs.add("Microsoft.WindowsMobile.DirectX"); forcedLibs.add("Microsoft.WindowsMobile.DirectX.Direct3D"); forcedLibs.add("Microsoft_VsaVb"); forcedLibs.add("RegCode"); forcedLibs.add("System"); forcedLibs.add("System.AddIn"); forcedLibs.add("System.AddIn.Contract"); forcedLibs.add("System.AddIn.Contract.Automation"); forcedLibs.add("System.AddIn.Contract.Collections"); forcedLibs.add("System.AddIn.Hosting"); forcedLibs.add("System.AddIn.Pipeline"); forcedLibs.add("System.CodeDom"); forcedLibs.add("System.CodeDom.Compiler"); forcedLibs.add("System.Collections"); forcedLibs.add("System.Collections.Generic"); forcedLibs.add("System.Collections.ObjectModel"); forcedLibs.add("System.Collections.Specialized"); forcedLibs.add("System.ComponentModel"); forcedLibs.add("System.ComponentModel.DataAnnotations"); forcedLibs.add("System.ComponentModel.Design"); forcedLibs.add("System.ComponentModel.Design.Data"); forcedLibs.add("System.ComponentModel.Design.Serialization"); forcedLibs.add("System.Configuration"); forcedLibs.add("System.Configuration.Assemblies"); forcedLibs.add("System.Configuration.Install"); forcedLibs.add("System.Configuration.Internal"); forcedLibs.add("System.Configuration.Provider"); forcedLibs.add("System.Data"); forcedLibs.add("System.Data.Common"); forcedLibs.add("System.Data.Common.CommandTrees"); forcedLibs.add("System.Data.Design"); forcedLibs.add("System.Data.Entity.Design"); forcedLibs.add("System.Data.Entity.Design.AspNet"); forcedLibs.add("System.Data.EntityClient"); forcedLibs.add("System.Data.Linq"); forcedLibs.add("System.Data.Linq.Mapping"); forcedLibs.add("System.Data.Linq.SqlClient"); forcedLibs.add("System.Data.Linq.SqlClient.Implementation"); forcedLibs.add("System.Data.Mapping"); forcedLibs.add("System.Data.Metadata.Edm"); forcedLibs.add("System.Data.Objects"); forcedLibs.add("System.Data.Objects.DataClasses"); forcedLibs.add("System.Data.Odbc"); forcedLibs.add("System.Data.OleDb"); forcedLibs.add("System.Data.OracleClient"); forcedLibs.add("System.Data.Services"); forcedLibs.add("System.Data.Services.Client"); forcedLibs.add("System.Data.Services.Common"); forcedLibs.add("System.Data.Services.Design"); forcedLibs.add("System.Data.Services.Internal"); forcedLibs.add("System.Data.Sql"); forcedLibs.add("System.Data.SqlClient"); forcedLibs.add("System.Data.SqlTypes"); forcedLibs.add("System.Deployment.Application"); forcedLibs.add("System.Deployment.Internal"); forcedLibs.add("System.Diagnostics"); forcedLibs.add("System.Diagnostics.CodeAnalysis"); forcedLibs.add("System.Diagnostics.Design"); forcedLibs.add("System.Diagnostics.Eventing"); forcedLibs.add("System.Diagnostics.Eventing.Reader"); forcedLibs.add("System.Diagnostics.PerformanceData"); forcedLibs.add("System.Diagnostics.SymbolStore"); forcedLibs.add("System.DirectoryServices"); forcedLibs.add("System.DirectoryServices.AccountManagement"); forcedLibs.add("System.DirectoryServices.ActiveDirectory"); forcedLibs.add("System.DirectoryServices.Protocols"); forcedLibs.add("System.Drawing"); forcedLibs.add("System.Drawing.Design"); forcedLibs.add("System.Drawing.Drawing2D"); forcedLibs.add("System.Drawing.Imaging"); forcedLibs.add("System.Drawing.Printing"); forcedLibs.add("System.Drawing.Text"); forcedLibs.add("System.EnterpriseServices"); forcedLibs.add("System.EnterpriseServices.CompensatingResourceManager"); forcedLibs.add("System.EnterpriseServices.Internal"); forcedLibs.add("System.Globalization"); forcedLibs.add("System.IdentityModel.Claims"); forcedLibs.add("System.IdentityModel.Policy"); forcedLibs.add("System.IdentityModel.Selectors"); forcedLibs.add("System.IdentityModel.Tokens"); forcedLibs.add("System.IO"); forcedLibs.add("System.IO.Compression"); forcedLibs.add("System.IO.IsolatedStorage"); forcedLibs.add("System.IO.Log"); forcedLibs.add("System.IO.Packaging"); forcedLibs.add("System.IO.Pipes"); forcedLibs.add("System.IO.Ports"); forcedLibs.add("System.Linq"); forcedLibs.add("System.Linq.Expressions"); forcedLibs.add("System.Management"); forcedLibs.add("System.Management.Instrumentation"); forcedLibs.add("System.Media"); forcedLibs.add("System.Messaging"); forcedLibs.add("System.Messaging.Design"); forcedLibs.add("System.Net"); forcedLibs.add("System.Net.Cache"); forcedLibs.add("System.Net.Configuration"); forcedLibs.add("System.Net.Mail"); forcedLibs.add("System.Net.Mime"); forcedLibs.add("System.Net.NetworkInformation"); forcedLibs.add("System.Net.PeerToPeer"); forcedLibs.add("System.Net.PeerToPeer.Collaboration"); forcedLibs.add("System.Net.Security"); forcedLibs.add("System.Net.Sockets"); forcedLibs.add("System.Printing"); forcedLibs.add("System.Printing.IndexedProperties"); forcedLibs.add("System.Printing.Interop"); forcedLibs.add("System.Reflection"); forcedLibs.add("System.Reflection.Emit"); forcedLibs.add("System.Resources"); forcedLibs.add("System.Resources.Tools"); forcedLibs.add("System.Runtime"); forcedLibs.add("System.Runtime.CompilerServices"); forcedLibs.add("System.Runtime.ConstrainedExecution"); forcedLibs.add("System.Runtime.Hosting"); forcedLibs.add("System.Runtime.InteropServices"); forcedLibs.add("System.Runtime.InteropServices.ComTypes"); forcedLibs.add("System.Runtime.InteropServices.CustomMarshalers"); forcedLibs.add("System.Runtime.InteropServices.Expando"); forcedLibs.add("System.Runtime.Remoting"); forcedLibs.add("System.Runtime.Remoting.Activation"); forcedLibs.add("System.Runtime.Remoting.Channels"); forcedLibs.add("System.Runtime.Remoting.Channels.Http"); forcedLibs.add("System.Runtime.Remoting.Channels.Ipc"); forcedLibs.add("System.Runtime.Remoting.Channels.Tcp"); forcedLibs.add("System.Runtime.Remoting.Contexts"); forcedLibs.add("System.Runtime.Remoting.Lifetime"); forcedLibs.add("System.Runtime.Remoting.Messaging"); forcedLibs.add("System.Runtime.Remoting.Metadata"); forcedLibs.add("System.Runtime.Remoting.MetadataServices"); forcedLibs.add("System.Runtime.Remoting.Proxies"); forcedLibs.add("System.Runtime.Remoting.Services"); forcedLibs.add("System.Runtime.Serialization"); forcedLibs.add("System.Runtime.Serialization.Configuration"); forcedLibs.add("System.Runtime.Serialization.Formatters"); forcedLibs.add("System.Runtime.Serialization.Formatters.Binary"); forcedLibs.add("System.Runtime.Serialization.Formatters.Soap"); forcedLibs.add("System.Runtime.Serialization.Json"); forcedLibs.add("System.Runtime.Versioning"); forcedLibs.add("System.Security"); forcedLibs.add("System.Security.AccessControl"); forcedLibs.add("System.Security.Authentication"); forcedLibs.add("System.Security.Authentication.ExtendedProtection"); forcedLibs.add("System.Security.Authentication.ExtendedProtection.Configuration"); forcedLibs.add("System.Security.Cryptography"); forcedLibs.add("System.Security.Cryptography.Pkcs"); forcedLibs.add("System.Security.Cryptography.X509Certificates"); forcedLibs.add("System.Security.Cryptography.Xml"); forcedLibs.add("System.Security.Permissions"); forcedLibs.add("System.Security.Policy"); forcedLibs.add("System.Security.Principal"); forcedLibs.add("System.Security.RightsManagement"); forcedLibs.add("System.ServiceModel"); forcedLibs.add("System.ServiceModel.Activation"); forcedLibs.add("System.ServiceModel.Activation.Configuration"); forcedLibs.add("System.ServiceModel.Channels"); forcedLibs.add("System.ServiceModel.ComIntegration"); forcedLibs.add("System.ServiceModel.Configuration"); forcedLibs.add("System.ServiceModel.Description"); forcedLibs.add("System.ServiceModel.Diagnostics"); forcedLibs.add("System.ServiceModel.Dispatcher"); forcedLibs.add("System.ServiceModel.Install.Configuration"); forcedLibs.add("System.ServiceModel.Internal"); forcedLibs.add("System.ServiceModel.MsmqIntegration"); forcedLibs.add("System.ServiceModel.PeerResolvers"); forcedLibs.add("System.ServiceModel.Persistence"); forcedLibs.add("System.ServiceModel.Security"); forcedLibs.add("System.ServiceModel.Security.Tokens"); forcedLibs.add("System.ServiceModel.Syndication"); forcedLibs.add("System.ServiceModel.Web"); forcedLibs.add("System.ServiceProcess"); forcedLibs.add("System.ServiceProcess.Design"); forcedLibs.add("System.Speech.AudioFormat"); forcedLibs.add("System.Speech.Recognition"); forcedLibs.add("System.Speech.Recognition.SrgsGrammar"); forcedLibs.add("System.Speech.Synthesis"); forcedLibs.add("System.Speech.Synthesis.TtsEngine"); forcedLibs.add("System.Text"); forcedLibs.add("System.Text.RegularExpressions"); forcedLibs.add("System.Threading"); forcedLibs.add("System.Timers"); forcedLibs.add("System.Transactions"); forcedLibs.add("System.Transactions.Configuration"); forcedLibs.add("System.Web"); forcedLibs.add("System.Web.ApplicationServices"); forcedLibs.add("System.Web.Caching"); forcedLibs.add("System.Web.ClientServices"); forcedLibs.add("System.Web.ClientServices.Providers"); forcedLibs.add("System.Web.Compilation"); forcedLibs.add("System.Web.Configuration"); forcedLibs.add("System.Web.Configuration.Internal"); forcedLibs.add("System.Web.DynamicData"); forcedLibs.add("System.Web.DynamicData.Design"); forcedLibs.add("System.Web.DynamicData.ModelProviders"); forcedLibs.add("System.Web.Handlers"); forcedLibs.add("System.Web.Hosting"); forcedLibs.add("System.Web.Mail"); forcedLibs.add("System.Web.Management"); forcedLibs.add("System.Web.Mobile"); forcedLibs.add("System.Web.Profile"); forcedLibs.add("System.Web.Query.Dynamic"); forcedLibs.add("System.Web.RegularExpressions"); forcedLibs.add("System.Web.Routing"); forcedLibs.add("System.Web.Script.Serialization"); forcedLibs.add("System.Web.Script.Services"); forcedLibs.add("System.Web.Security"); forcedLibs.add("System.Web.Services"); forcedLibs.add("System.Web.Services.Configuration"); forcedLibs.add("System.Web.Services.Description"); forcedLibs.add("System.Web.Services.Discovery"); forcedLibs.add("System.Web.Services.Protocols"); forcedLibs.add("System.Web.SessionState"); forcedLibs.add("System.Web.UI"); forcedLibs.add("System.Web.UI.Adapters"); forcedLibs.add("System.Web.UI.Design"); forcedLibs.add("System.Web.UI.Design.MobileControls"); forcedLibs.add("System.Web.UI.Design.MobileControls.Converters"); forcedLibs.add("System.Web.UI.Design.WebControls"); forcedLibs.add("System.Web.UI.Design.WebControls.WebParts"); forcedLibs.add("System.Web.UI.MobileControls"); forcedLibs.add("System.Web.UI.MobileControls.Adapters"); forcedLibs.add("System.Web.UI.MobileControls.Adapters.XhtmlAdapters"); forcedLibs.add("System.Web.UI.WebControls"); forcedLibs.add("System.Web.UI.WebControls.Adapters"); forcedLibs.add("System.Web.UI.WebControls.WebParts"); forcedLibs.add("System.Web.Util"); forcedLibs.add("System.Windows"); forcedLibs.add("System.Windows.Annotations"); forcedLibs.add("System.Windows.Annotations.Storage"); forcedLibs.add("System.Windows.Automation"); forcedLibs.add("System.Windows.Automation.Peers"); forcedLibs.add("System.Windows.Automation.Provider"); forcedLibs.add("System.Windows.Automation.Text"); forcedLibs.add("System.Windows.Controls"); forcedLibs.add("System.Windows.Controls.Primitives"); forcedLibs.add("System.Windows.Converters"); forcedLibs.add("System.Windows.Data"); forcedLibs.add("System.Windows.Documents"); forcedLibs.add("System.Windows.Documents.Serialization"); forcedLibs.add("System.Windows.Forms"); forcedLibs.add("System.Windows.Forms.ComponentModel.Com2Interop"); forcedLibs.add("System.Windows.Forms.Design"); forcedLibs.add("System.Windows.Forms.Design.Behavior"); forcedLibs.add("System.Windows.Forms.Integration"); forcedLibs.add("System.Windows.Forms.Layout"); forcedLibs.add("System.Windows.Forms.PropertyGridInternal"); forcedLibs.add("System.Windows.Forms.VisualStyles"); forcedLibs.add("System.Windows.Ink"); forcedLibs.add("System.Windows.Ink.AnalysisCore"); forcedLibs.add("System.Windows.Input"); forcedLibs.add("System.Windows.Input.StylusPlugIns"); forcedLibs.add("System.Windows.Interop"); forcedLibs.add("System.Windows.Markup"); forcedLibs.add("System.Windows.Markup.Localizer"); forcedLibs.add("System.Windows.Markup.Primitives"); forcedLibs.add("System.Windows.Media"); forcedLibs.add("System.Windows.Media.Animation"); forcedLibs.add("System.Windows.Media.Converters"); forcedLibs.add("System.Windows.Media.Effects"); forcedLibs.add("System.Windows.Media.Imaging"); forcedLibs.add("System.Windows.Media.Media3D"); forcedLibs.add("System.Windows.Media.Media3D.Converters"); forcedLibs.add("System.Windows.Media.TextFormatting"); forcedLibs.add("System.Windows.Navigation"); forcedLibs.add("System.Windows.Resources"); forcedLibs.add("System.Windows.Shapes"); forcedLibs.add("System.Windows.Threading"); forcedLibs.add("System.Windows.Xps"); forcedLibs.add("System.Windows.Xps.Packaging"); forcedLibs.add("System.Windows.Xps.Serialization"); forcedLibs.add("System.Workflow.Activities"); forcedLibs.add("System.Workflow.Activities.Configuration"); forcedLibs.add("System.Workflow.Activities.Rules"); forcedLibs.add("System.Workflow.Activities.Rules.Design"); forcedLibs.add("System.Workflow.ComponentModel"); forcedLibs.add("System.Workflow.ComponentModel.Compiler"); forcedLibs.add("System.Workflow.ComponentModel.Design"); forcedLibs.add("System.Workflow.ComponentModel.Serialization"); forcedLibs.add("System.Workflow.Runtime"); forcedLibs.add("System.Workflow.Runtime.Configuration"); forcedLibs.add("System.Workflow.Runtime.DebugEngine"); forcedLibs.add("System.Workflow.Runtime.Hosting"); forcedLibs.add("System.Workflow.Runtime.Tracking"); forcedLibs.add("System.Xml"); forcedLibs.add("System.Xml.Linq"); forcedLibs.add("System.Xml.Schema"); forcedLibs.add("System.Xml.Serialization"); forcedLibs.add("System.Xml.Serialization.Advanced"); forcedLibs.add("System.Xml.Serialization.Configuration"); forcedLibs.add("System.Xml.XPath"); forcedLibs.add("System.Xml.Xsl"); forcedLibs.add("System.Xml.Xsl.Runtime"); forcedLibs.add("UIAutomationClientsideProviders"); break; default: throw new RuntimeException("Don't know how to treat: " + interpreterType); } this.clearBuiltinsCache(); //force cache recreation } private void addForcedLibsFor(String lib) { //For now only adds "werkzeug", but this is meant as an extension place. File file = new File(lib); if (file.exists()) { if (file.isDirectory()) { //check as dir (if it has a werkzeug folder) File werkzeug = new File(file, "werkzeug"); if (werkzeug.isDirectory()) { forcedLibs.add("werkzeug"); } } else { //check as zip (if it has a werkzeug entry -- note that we have to check the __init__ //because an entry just with the folder doesn't really exist) try { ZipFile zipFile = new ZipFile(file); if (zipFile.getEntry("werkzeug/__init__.py") != null) { forcedLibs.add("werkzeug"); } } catch (Exception e) { //ignore (not zip file) } } } } // Initially I thought werkzeug would need to add all the contents, so, this was a prototype to // analyze it and add what's needed (but it turns out that just adding werkzeug is ok. // protected void handleWerkzeug(File initWerkzeug) { // String fileContents = FileUtils.getFileContents(initWerkzeug); // Tuple<SimpleNode, Throwable> parse = PyParser.reparseDocument( // new PyParser.ParserInfo(new Document(fileContents), false, this.getGrammarVersion())); // Module o1 = (Module) parse.o1; // forcedLibs.add("werkzeug"); // for(stmtType stmt:o1.body){ // if(stmt instanceof Assign){ // Assign assign = (Assign) stmt; // if(assign.targets.length == 1){ // if(assign.value instanceof Dict){ // String rep = NodeUtils.getRepresentationString(assign.targets[0]); // if("all_by_module".equals(rep)){ // Dict dict = (Dict) assign.value; // for(exprType key:dict.keys){ // if(key instanceof Str){ // Str str = (Str) key; // forcedLibs.add(str.s); // } // } // } // }else if(assign.value instanceof Call){ // String rep = NodeUtils.getRepresentationString(assign.targets[0]); // if("attribute_modules".equals(rep)){ // Call call = (Call) assign.value; // rep = NodeUtils.getRepresentationString(call.func); // if("fromkeys".equals(rep)){ // if(call.args.length == 1){ // if(call.args[0] instanceof org.python.pydev.parser.jython.ast.List){ // org.python.pydev.parser.jython.ast.List list = (org.python.pydev.parser.jython.ast.List) call.args[0]; // for(exprType elt:list.elts){ // if(elt instanceof Str){ // Str str = (Str) elt; // forcedLibs.add("werkzeug."+str.s); // } // } // // } // } // } // } // } // } // } // } // } private void clearBuiltinsCache() { this.builtinsCache = null; //force cache recreation this.predefinedBuiltinsCache = null; } /** * Restores the path given non-standard libraries * @param path */ private void restorePythonpath(String path, IProgressMonitor monitor) { //no managers involved here... getModulesManager().changePythonPath(path, null, monitor); } /** * Restores the path with the discovered libs * @param path */ public void restorePythonpath(IProgressMonitor monitor) { FastStringBuffer buffer = new FastStringBuffer(); for (Iterator<String> iter = libs.iterator(); iter.hasNext();) { String folder = (String) iter.next(); buffer.append(folder); buffer.append("|"); } restorePythonpath(buffer.toString(), monitor); } public int getInterpreterType() { if (isJythonExecutable(executableOrJar)) { return IInterpreterManager.INTERPRETER_TYPE_JYTHON; } else if (isIronpythonExecutable(executableOrJar)) { return IInterpreterManager.INTERPRETER_TYPE_IRONPYTHON; } //neither one: it's python. return IInterpreterManager.INTERPRETER_TYPE_PYTHON; } /** * @param executable the executable we want to know about * @return if the executable is the jython jar. */ public static boolean isJythonExecutable(String executable) { if (executable.endsWith("\"")) { return executable.endsWith(".jar\""); } return executable.endsWith(".jar"); } /** * @param executable the executable we want to know about * @return if the executable is the ironpython executable. */ public static boolean isIronpythonExecutable(String executable) { File file = new File(executable); return file.getName().startsWith("ipy"); } public static String getExeAsFileSystemValidPath(String executableOrJar) { return StringUtils.getExeAsFileSystemValidPath(executableOrJar); } public String getExeAsFileSystemValidPath() { return getExeAsFileSystemValidPath(executableOrJar); } public String getVersion() { return version; } public int getGrammarVersion() { return PythonNature.getGrammarVersionFromStr(version); } //START: Things related to the builtins (forcedLibs) --------------------------------------------------------------- public String[] getBuiltins() { if (this.builtinsCache == null) { Set<String> set = new HashSet<String>(forcedLibs); this.builtinsCache = set.toArray(new String[0]); } return this.builtinsCache; } public void addForcedLib(String forcedLib) { if (isForcedLibToIgnore(forcedLib)) { return; } this.forcedLibs.add(forcedLib); this.clearBuiltinsCache(); } /** * @return true if the passed forced lib should not be added to the forced builtins. */ private boolean isForcedLibToIgnore(String forcedLib) { if (forcedLib == null) { return true; } //We want django to be always analyzed as source for (String s : LIBRARIES_TO_IGNORE_AS_FORCED_BUILTINS) { if (forcedLib.equals(s) || forcedLib.startsWith(s + ".")) { return true; } } return false; } public void removeForcedLib(String forcedLib) { this.forcedLibs.remove(forcedLib); this.clearBuiltinsCache(); } public Iterator<String> forcedLibsIterator() { return forcedLibs.iterator(); } //END: Things related to the builtins (forcedLibs) ----------------------------------------------------------------- /** * Sets the environment variables to be kept in the interpreter info. * * Some notes: * - Will remove (and warn) about any PYTHONPATH env. var. * - Will keep the env. variables sorted internally. */ public void setEnvVariables(String[] env) { if (env != null) { ArrayList<String> lst = new ArrayList<String>(); //We must make sure that the PYTHONPATH is not in the env. variables. for (String s : env) { Tuple<String, String> sp = StringUtils.splitOnFirst(s, '='); if (sp.o1.length() != 0 && sp.o2.length() != 0) { if (!checkIfPythonPathEnvVarAndWarnIfIs(sp.o1)) { lst.add(s); } } } Collections.sort(lst); env = lst.toArray(new String[lst.size()]); } if (env != null && env.length == 0) { env = null; } this.envVariables = env; } public String[] getEnvVariables() { return this.envVariables; } public String[] updateEnv(String[] env) { return updateEnv(env, null); } public String[] updateEnv(String[] env, Set<String> keysThatShouldNotBeUpdated) { if (this.envVariables == null || this.envVariables.length == 0) { return env; //nothing to change } //Ok, it's not null... //let's merge them (env may be null/zero-length but we need to apply variable resolver to envVariables anyway) HashMap<String, String> hashMap = new HashMap<String, String>(); fillMapWithEnv(env, hashMap, null, null); fillMapWithEnv(envVariables, hashMap, keysThatShouldNotBeUpdated, getStringVariableManager()); //will override the keys already there unless they're in keysThatShouldNotBeUpdated String[] ret = createEnvWithMap(hashMap); return ret; } public static String[] createEnvWithMap(Map<String, String> hashMap) { Set<Entry<String, String>> entrySet = hashMap.entrySet(); String[] ret = new String[entrySet.size()]; int i = 0; for (Entry<String, String> entry : entrySet) { ret[i] = entry.getKey() + "=" + entry.getValue(); i++; } return ret; } public static void fillMapWithEnv(String[] env, HashMap<String, String> hashMap, Set<String> keysThatShouldNotBeUpdated, IStringVariableManager manager) { if (env == null || env.length == 0) { // nothing to do return; } if (keysThatShouldNotBeUpdated == null) { keysThatShouldNotBeUpdated = Collections.emptySet(); } for (String s : env) { Tuple<String, String> sp = StringUtils.splitOnFirst(s, '='); if (sp.o1.length() != 0 && sp.o2.length() != 0 && !keysThatShouldNotBeUpdated.contains(sp.o1)) { String value = sp.o2; if (manager != null) { try { value = manager.performStringSubstitution(value, false); } catch (CoreException e) { // Unreachable as false passed to reportUndefinedVariables above } } hashMap.put(sp.o1, value); } } } /** * This function will remove any PYTHONPATH entry from the given map (considering the case based on the system) * and will give a warning to the user if that's actually done. */ public static void removePythonPathFromEnvMapWithWarning(HashMap<String, String> map) { if (map == null) { return; } for (Iterator<Map.Entry<String, String>> it = map.entrySet().iterator(); it.hasNext();) { Map.Entry<String, String> next = it.next(); String key = next.getKey(); if (checkIfPythonPathEnvVarAndWarnIfIs(key)) { it.remove(); } } } /** * Warns if the passed key is the PYTHONPATH env. var. * * @param key the key to check. * @return true if the passed key is a PYTHONPATH env. var. (considers platform) */ public static boolean checkIfPythonPathEnvVarAndWarnIfIs(String key) { boolean isPythonPath = false; boolean win32 = PlatformUtils.isWindowsPlatform(); if (win32) { key = key.toUpperCase(); } final String keyPlatformDependent = key; if (keyPlatformDependent.equals("PYTHONPATH") || keyPlatformDependent.equals("CLASSPATH") || keyPlatformDependent.equals("JYTHONPATH") || keyPlatformDependent.equals("IRONPYTHONPATH")) { final String msg = "Ignoring " + keyPlatformDependent + " specified in the interpreter info.\n" + "It's managed depending on the project and other configurations and cannot be directly specified in the interpreter."; try { RunInUiThread.async(new Runnable() { public void run() { MessageBox message = new MessageBox(PyAction.getShell(), SWT.OK | SWT.ICON_INFORMATION); message.setText("Ignoring " + keyPlatformDependent); message.setMessage(msg); message.open(); } }); } catch (Throwable e) { // ignore error communication error } Log.log(IStatus.WARNING, msg, null); isPythonPath = true; } return isPythonPath; } /** * @return a new interpreter info that's a copy of the current interpreter info. */ public InterpreterInfo makeCopy() { return fromString(toString(), false); } public void setName(String name) { this.name = name; } public String getName() { if (this.name != null) { return this.name; } return this.executableOrJar; } public String getNameForUI() { if (this.name != null) { return this.name + " (" + this.executableOrJar + ")"; } else { return this.executableOrJar; } } public boolean matchNameBackwardCompatible(String interpreter) { if (this.name != null) { if (interpreter.equals(this.name)) { return true; } } if (PlatformUtils.isWindowsPlatform()) { return interpreter.equalsIgnoreCase(executableOrJar); } return interpreter.equals(executableOrJar); } public void setStringSubstitutionVariables(Properties stringSubstitutionOriginal) { if (stringSubstitutionOriginal == null) { this.stringSubstitutionVariables = null; } else { this.stringSubstitutionVariables = stringSubstitutionOriginal; } } public Properties getStringSubstitutionVariables() { return this.stringSubstitutionVariables; } public void addPredefinedCompletionsPath(String path) { this.predefinedCompletionsPath.add(path); this.clearBuiltinsCache(); } public List<String> getPredefinedCompletionsPath() { return new ArrayList<String>(predefinedCompletionsPath); //Return a copy. } /** * May return null if it doesn't exist. * @return the file that matches the passed module name with the predefined builtins. */ public File getPredefinedModule(String moduleName) { if (this.predefinedBuiltinsCache == null) { this.predefinedBuiltinsCache = new HashMap<String, File>(); for (String s : this.getPredefinedCompletionsPath()) { File f = new File(s); if (f.exists()) { File[] predefs = f.listFiles(new FilenameFilter() { //Only accept names ending with .pypredef in the passed dirs public boolean accept(File dir, String name) { return name.endsWith(".pypredef"); } }); if (predefs != null) { for (File file : predefs) { String n = file.getName(); String modName = n.substring(0, n.length() - (".pypredef".length())); this.predefinedBuiltinsCache.put(modName, file); } } } } } return this.predefinedBuiltinsCache.get(moduleName); } public void removePredefinedCompletionPath(String item) { this.predefinedCompletionsPath.remove(item); this.clearBuiltinsCache(); } private IInterpreterInfoBuilder builder; private final Object builderLock = new Object(); private volatile boolean loadFinished = true; /** * Building so that the interpreter info is kept up to date. */ public void startBuilding() { synchronized (builderLock) { if (this.builder == null) { IInterpreterInfoBuilder builder = (IInterpreterInfoBuilder) ExtensionHelper.getParticipant( ExtensionHelper.PYDEV_INTERPRETER_INFO_BUILDER, false); if (builder != null) { builder.setInfo(this); this.builder = builder; } else { if (!ProjectModulesManager.IN_TESTS) { Log.log("Could not get internal extension for: " + ExtensionHelper.PYDEV_INTERPRETER_INFO_BUILDER); } } } } } public void stopBuilding() { synchronized (builderLock) { if (this.builder != null) { this.builder.dispose(); this.builder = null; } } } public void setLoadFinished(boolean b) { this.loadFinished = b; } public boolean getLoadFinished() { return this.loadFinished; } }