Merge branch 'master' into traff/zip_helpers
authorDmitry Trofimov <dmitry.trofimov@jetbrains.com>
Mon, 21 Sep 2015 12:55:25 +0000 (14:55 +0200)
committerDmitry Trofimov <dmitry.trofimov@jetbrains.com>
Mon, 21 Sep 2015 12:55:25 +0000 (14:55 +0200)
1  2 
python/helpers/pydev/pydevd.py
python/python-rest/src/com/jetbrains/rest/sphinx/SphinxBaseCommand.java
python/src/com/jetbrains/python/PythonHelper.java
python/src/com/jetbrains/python/PythonHelpersLocator.java
python/src/com/jetbrains/python/console/PydevConsoleRunner.java
python/src/com/jetbrains/python/debugger/PyDebugRunner.java
python/src/com/jetbrains/python/documentation/docstrings/PyStructuredDocstringFormatter.java
python/src/com/jetbrains/python/run/PythonCommandLineState.java
python/src/com/jetbrains/python/run/PythonTask.java
python/src/com/jetbrains/python/sdk/PythonSdkType.java

Simple merge
index 12d041ba3c98c0c9feb93ebb7efd794ca3df3dd1,0000000000000000000000000000000000000000..e5f57b052926ade5e87d611bd498ab9ef8b8fd99
mode 100644,000000..100644
--- /dev/null
@@@ -1,211 -1,0 +1,213 @@@
 +/*
 + * Copyright 2000-2015 JetBrains s.r.o.
 + *
 + * Licensed under the Apache License, Version 2.0 (the "License");
 + * you may not use this file except in compliance with the License.
 + * You may obtain a copy of the License at
 + *
 + * http://www.apache.org/licenses/LICENSE-2.0
 + *
 + * Unless required by applicable law or agreed to in writing, software
 + * distributed under the License is distributed on an "AS IS" BASIS,
 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 + * See the License for the specific language governing permissions and
 + * limitations under the License.
 + */
 +package com.jetbrains.python;
 +
 +import com.google.common.collect.Lists;
 +import com.intellij.execution.configurations.GeneralCommandLine;
 +import com.intellij.execution.configurations.ParamsGroup;
 +import com.intellij.openapi.util.io.FileUtil;
 +import com.jetbrains.python.sdk.PythonEnvUtil;
 +import org.jetbrains.annotations.NotNull;
 +
 +import java.io.File;
 +import java.util.List;
 +import java.util.Map;
 +
 +import static com.jetbrains.python.PythonHelpersLocator.getHelperFile;
 +import static com.jetbrains.python.PythonHelpersLocator.getHelpersRoot;
 +
 +/**
 + * @author traff
 + */
 +public enum PythonHelper implements HelperPackage {
 +  COVERAGEPY("coveragepy", ""), COVERAGE("coverage_runner", "run_coverage"),
 +  DEBUGGER("pydev", "pydevd"),
 +  ATTACH_DEBUGGER("pydev", "pydevd_attach_to_process.attach_pydevd"),
 +
 +  CONSOLE("pydev", "pydevconsole"),
 +  RUN_IN_CONSOLE("pydev", "pydev_run_in_console"),
 +  PROFILER("profiler", "run_profiler"),
 +
 +  LOAD_ENTRY_POINT("pycharm", "pycharm_load_entry_point"),
 +
 +  // Test runners
 +  UT("pycharm", "utrunner"),
 +  SETUPPY("pycharm", "pycharm_setup_runner"),
 +  NOSE("pycharm", "noserunner"),
 +  PYTEST("pycharm", "pytestrunner"),
 +  ATTEST("pycharm", "attestrunner"),
 +  DOCSTRING("pycharm", "docrunner"),
 +
 +  BEHAVE("pycharm", "behave_runner"),
 +  LETTUCE("pycharm", "lettuce_runner"),
 +
 +  DJANGO_TEST_MANAGE("pycharm", "django_test_manage"),
 +  DJANGO_MANAGE("pycharm", "django_manage"),
 +  MANAGE_TASKS_PROVIDER("pycharm", "_jb_manage_tasks_provider"),
 +
 +  BUILDOUT_ENGULFER("pycharm", "buildout_engulfer"),
 +
 +  EPYDOC_FORMATTER("epydoc_formatter.py"),
 +  REST_FORMATTER("rest_formatter.py"),
++  GOOGLE_FORMATTER("google_formatter.py"),
++  NUMPY_FORMATTER("numpy_formatter.py"),
 +
 +  EXTRA_SYSPATH("extra_syspath.py"),
 +  SYSPATH("syspath.py"),
 +
 +  PEP8("pep8.py"),
 +
 +  REST_RUNNER("rest_runners/rst2smth.py"),
 +
 +  SPHINX_RUNNER("rest_runners/sphinx_runner.py");
 +
 +  @NotNull
 +  private static PathHelperPackage findModule(String moduleEntryPoint, String path, boolean asModule) {
 +    if (getHelperFile(path + ".zip").isFile()) {
 +      return new ModuleHelperPackage(moduleEntryPoint, path + ".zip");
 +    }
 +
 +    if (!asModule && new File(getHelperFile(path), moduleEntryPoint + ".py").isFile()) {
 +      return new ScriptPythonHelper(moduleEntryPoint + ".py", getHelperFile(path));
 +    }
 +
 +    return new ModuleHelperPackage(moduleEntryPoint, path);
 +  }
 +
 +  private PathHelperPackage myModule;
 +
 +  PythonHelper(String pythonPath, String moduleName) {
 +    this(pythonPath, moduleName, false);
 +  }
 +
 +  PythonHelper(String pythonPath, String moduleName, boolean asModule) {
 +    myModule = findModule(moduleName, pythonPath, asModule);
 +  }
 +
 +  PythonHelper(String helperScript) {
 +    myModule = new ScriptPythonHelper(helperScript, getHelpersRoot());
 +  }
 +
 +
 +  public String getPythonPath() {
 +    return myModule.getPythonPath();
 +  }
 +
 +  public abstract static class PathHelperPackage implements HelperPackage {
 +    protected final File myPath;
 +
 +    PathHelperPackage(String path) {
 +      myPath = new File(path);
 +    }
 +
 +    @Override
 +    public void addToPythonPath(@NotNull Map<String, String> environment) {
 +      PythonEnvUtil.addToPythonPath(environment, myPath.getAbsolutePath());
 +    }
 +
 +    @Override
 +    public void addToGroup(@NotNull ParamsGroup group, @NotNull GeneralCommandLine cmd) {
 +      addToPythonPath(cmd.getEnvironment());
 +      group.addParameter(asParamString());
 +    }
 +
 +    @Override
 +    public String asParamString() {
 +      return FileUtil.toSystemDependentName(myPath.getAbsolutePath());
 +    }
 +
 +    @Override
 +    public GeneralCommandLine newCommandLine(String sdkPath, List<String> parameters) {
 +      List<String> args = Lists.newArrayList();
 +      args.add(sdkPath);
 +      args.add(asParamString());
 +      args.addAll(parameters);
 +      GeneralCommandLine cmd = new GeneralCommandLine(args);
 +      addToPythonPath(cmd.getEnvironment());
 +      return cmd;
 +    }
 +  }
 +
 +  /**
 +   * Module Python helper can be executed from zip-archive
 +   */
 +  public static class ModuleHelperPackage extends PathHelperPackage {
 +    private final String myModuleName;
 +
 +    public ModuleHelperPackage(String moduleName, String relativePath) {
 +      super(getHelperFile(relativePath).getAbsolutePath());
 +      this.myModuleName = moduleName;
 +    }
 +
 +    @Override
 +    public String asParamString() {
 +      return "-m" + myModuleName;
 +    }
 +
 +    @Override
 +    public String getPythonPath() {
 +      return FileUtil.toSystemDependentName(myPath.getAbsolutePath());
 +    }
 +  }
 +
 +  /**
 +   * Script Python helper can be executed as a Python script, therefore
 +   * PYTHONDONTWRITEBYTECODE option is set not to spoil installation
 +   * with .pyc files
 +   */
 +  public static class ScriptPythonHelper extends PathHelperPackage {
 +    private String myPythonPath;
 +
 +    public ScriptPythonHelper(String script, File pythonPath) {
 +      super(new File(pythonPath, script).getAbsolutePath());
 +      myPythonPath = pythonPath.getAbsolutePath();
 +    }
 +
 +    @Override
 +    public void addToPythonPath(@NotNull Map<String, String> environment) {
 +      PythonEnvUtil.setPythonDontWriteBytecode(environment);
 +      PythonEnvUtil.addToPythonPath(environment, myPythonPath);
 +    }
 +
 +    @Override
 +    public String getPythonPath() {
 +      return myPythonPath;
 +    }
 +  }
 +
 +
 +  @Override
 +  public void addToPythonPath(@NotNull Map<String, String> environment) {
 +    myModule.addToPythonPath(environment);
 +  }
 +
 +  @Override
 +  public void addToGroup(@NotNull ParamsGroup group, @NotNull GeneralCommandLine cmd) {
 +    myModule.addToGroup(group, cmd);
 +  }
 +
 +
 +  @Override
 +  public String asParamString() {
 +    return myModule.asParamString();
 +  }
 +
 +  @Override
 +  public GeneralCommandLine newCommandLine(String sdkPath, List<String> parameters) {
 +    return myModule.newCommandLine(sdkPath, parameters);
 +  }
 +
 +}
index 0000000000000000000000000000000000000000,526af32c444c39ab6cd65f3c11b4c18f4535fbcc..aa509a33f1a2d488bab67dbfcd33ad0738db1d88
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,216 +1,218 @@@
 -import com.jetbrains.python.PythonHelpersLocator;
+ /*
+  * Copyright 2000-2014 JetBrains s.r.o.
+  *
+  * Licensed under the Apache License, Version 2.0 (the "License");
+  * you may not use this file except in compliance with the License.
+  * You may obtain a copy of the License at
+  *
+  * http://www.apache.org/licenses/LICENSE-2.0
+  *
+  * Unless required by applicable law or agreed to in writing, software
+  * distributed under the License is distributed on an "AS IS" BASIS,
+  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  * See the License for the specific language governing permissions and
+  * limitations under the License.
+  */
+ package com.jetbrains.python.documentation.docstrings;
+ import com.google.common.collect.Lists;
+ import com.intellij.execution.process.ProcessOutput;
+ import com.intellij.openapi.diagnostic.Logger;
+ import com.intellij.openapi.module.Module;
+ import com.intellij.openapi.module.ModuleManager;
+ import com.intellij.openapi.module.ModuleUtilCore;
+ import com.intellij.openapi.projectRoots.Sdk;
+ import com.intellij.openapi.util.text.StringUtil;
+ import com.intellij.openapi.vfs.encoding.EncodingProjectManager;
+ import com.intellij.psi.PsiElement;
 -    final String formatter;
++import com.jetbrains.python.HelperPackage;
++import com.jetbrains.python.PythonHelper;
+ import com.jetbrains.python.documentation.PyDocumentationBuilder;
+ import com.jetbrains.python.psi.StructuredDocString;
+ import com.jetbrains.python.sdk.PySdkUtil;
+ import com.jetbrains.python.sdk.PythonEnvUtil;
+ import com.jetbrains.python.sdk.PythonSdkType;
+ import com.jetbrains.python.toolbox.Substring;
+ import org.jetbrains.annotations.NotNull;
+ import org.jetbrains.annotations.Nullable;
+ import java.io.File;
+ import java.nio.ByteBuffer;
+ import java.nio.charset.Charset;
+ import java.util.ArrayList;
+ import java.util.HashMap;
+ import java.util.List;
+ import java.util.Map;
+ /**
+  * @author yole
+  */
+ public class PyStructuredDocstringFormatter {
+   private static final Logger LOG = Logger.getInstance(PyStructuredDocstringFormatter.class);
+   private PyStructuredDocstringFormatter() {
+   }
+   @Nullable
+   public static List<String> formatDocstring(@NotNull final PsiElement element, @NotNull final String docstring) {
+     Module module = ModuleUtilCore.findModuleForPsiElement(element);
+     if (module == null) {
+       final Module[] modules = ModuleManager.getInstance(element.getProject()).getModules();
+       if (modules.length == 0) return Lists.newArrayList();
+       module = modules[0];
+     }
+     if (module == null) return Lists.newArrayList();
+     final List<String> result = new ArrayList<String>();
+     final String[] lines = PyDocumentationBuilder.removeCommonIndentation(docstring);
+     final String preparedDocstring = StringUtil.join(lines, "\n");
 -      formatter = PythonHelpersLocator.getHelperPath("google_formatter.py");
++    final HelperPackage formatter;
+     final StructuredDocString structuredDocString;
+     final DocStringFormat format = DocStringUtil.guessDocStringFormat(preparedDocstring, element);
+     if (format == DocStringFormat.GOOGLE) {
 -      formatter = PythonHelpersLocator.getHelperPath("numpy_formatter.py");
++      formatter = PythonHelper.GOOGLE_FORMATTER;
+       structuredDocString = DocStringUtil.parseDocString(DocStringFormat.GOOGLE, preparedDocstring);
+     }
+     else if (format == DocStringFormat.NUMPY) {
 -      formatter = PythonHelpersLocator.getHelperPath("epydoc_formatter.py");
++      formatter = PythonHelper.NUMPY_FORMATTER;
+       structuredDocString = DocStringUtil.parseDocString(DocStringFormat.NUMPY, preparedDocstring);
+     }
+     else if (format == DocStringFormat.EPYTEXT) {
 -      formatter = PythonHelpersLocator.getHelperPath("rest_formatter.py");
++      formatter = PythonHelper.EPYDOC_FORMATTER;
+       structuredDocString = DocStringUtil.parseDocString(DocStringFormat.EPYTEXT, preparedDocstring);
+       result.add(formatStructuredDocString(structuredDocString));
+     }
+     else if (format == DocStringFormat.REST) {
 -                                        @NotNull final String formatter,
++      formatter = PythonHelper.REST_FORMATTER;
+       structuredDocString = DocStringUtil.parseDocString(DocStringFormat.REST, preparedDocstring);
+     }
+     else {
+       return null;
+     }
+     final String output = runExternalTool(module, formatter, docstring);
+     if (output != null) {
+       result.add(0, output);
+     }
+     else {
+       result.add(0, structuredDocString.getDescription());
+     }
+     return result;
+   }
+   @Nullable
+   private static String runExternalTool(@NotNull final Module module,
 -    final ProcessOutput output = PySdkUtil.getProcessOutput(new File(sdkHome).getParent(), new String[]{sdkHome, formatter},
++                                        @NotNull final HelperPackage formatter,
+                                         @NotNull final String docstring) {
+     final Sdk sdk = PythonSdkType.findPython2Sdk(module);
+     if (sdk == null) return null;
+     final String sdkHome = sdk.getHomePath();
+     if (sdkHome == null) return null;
+     final Charset charset = EncodingProjectManager.getInstance(module.getProject()).getDefaultCharset();
+     final ByteBuffer encoded = charset.encode(docstring);
+     final byte[] data = new byte[encoded.limit()];
+     encoded.get(data);
+     final Map<String, String> env = new HashMap<String, String>();
+     PythonEnvUtil.setPythonDontWriteBytecode(env);
++    final ProcessOutput output = PySdkUtil.getProcessOutput(formatter.newCommandLine(sdkHome, Lists.<String>newArrayList()),
++                                                            new File(sdkHome).getParent(),
+                                                             env, 5000, data, true);
+     if (output.isTimeout()) {
+       LOG.info("timeout when calculating docstring");
+       return null;
+     }
+     else if (output.getExitCode() != 0) {
+       final String error = "error when calculating docstring: " + output.getStderr();
+       LOG.info(error);
+       return null;
+     }
+     return output.getStdout();
+   }
+   private static String formatStructuredDocString(@NotNull final StructuredDocString docString) {
+     final StringBuilder result = new StringBuilder();
+     final String attributeDescription = docString.getAttributeDescription();
+     if (attributeDescription != null) {
+       result.append(attributeDescription);
+       final String attrType = docString.getParamType(null);
+       if (attrType != null) {
+         result.append(" <i>Type: ").append(attrType).append("</i>");
+       }
+     }
+     formatParameterDescriptions(docString, result, false);
+     formatParameterDescriptions(docString, result, true);
+     final String returnDescription = docString.getReturnDescription();
+     final String returnType = docString.getReturnType();
+     if (returnDescription != null || returnType != null) {
+       result.append("<br><b>Return value:</b><br>");
+       if (returnDescription != null) {
+         result.append(returnDescription);
+       }
+       if (returnType != null) {
+         result.append(" <i>Type: ").append(returnType).append("</i>");
+       }
+     }
+     final List<String> raisedException = docString.getRaisedExceptions();
+     if (raisedException.size() > 0) {
+       result.append("<br><b>Raises:</b><br>");
+       for (String s : raisedException) {
+         result.append("<b>").append(s).append("</b> - ").append(docString.getRaisedExceptionDescription(s)).append("<br>");
+       }
+     }
+     if (docString instanceof TagBasedDocString) {
+       final TagBasedDocString taggedDocString = (TagBasedDocString)docString;
+       final List<String> additionalTags = taggedDocString.getAdditionalTags();
+       if (!additionalTags.isEmpty()) {
+         result.append("<br/><br/><b>Additional:</b><br/>");
+         result.append("<table>");
+         for (String tagName : additionalTags) {
+           final List<Substring> args = taggedDocString.getTagArguments(tagName);
+           for (Substring arg : args) {
+             final String s = arg.toString();
+             result.append("<tr><td align=\"right\"><b>").append(tagName);
+             result.append(" ").append(s).append(":</b>");
+             result.append("</td><td>").append(taggedDocString.getTagValue(tagName, s)).append("</td></tr>");
+           }
+           result.append("</table>");
+         }
+       }
+     }
+     return result.toString();
+   }
+   private static void formatParameterDescriptions(@NotNull final StructuredDocString docString,
+                                                   @NotNull final StringBuilder result,
+                                                   boolean keyword) {
+     final List<String> parameters = keyword ? docString.getKeywordArguments() : docString.getParameters();
+     if (parameters.size() > 0) {
+       result.append("<br><b>").append(keyword ? "Keyword arguments:" : "Parameters").append("</b><br>");
+       for (String parameter : parameters) {
+         final String description = keyword ? docString.getKeywordArgumentDescription(parameter) : docString.getParamDescription(parameter);
+         result.append("<b>");
+         result.append(parameter);
+         result.append("</b>: ");
+         if (description != null) {
+           result.append(description);
+         }
+         final String paramType = docString.getParamType(parameter);
+         if (paramType != null) {
+           result.append(" <i>Type: ").append(paramType).append("</i>");
+         }
+         result.append("<br>");
+       }
+     }
+   }
+ }
index 79c51cb584f275dc489dc4fed75b9ff7f394043d,e1c4cce34fd819cd4217fdf42e063b8454c19ff2..4d9d9b350bb4b223aaa22b0fb2eedf0e27246f47
@@@ -289,9 -278,9 +290,9 @@@ public abstract class PythonCommandLine
  
      commandLine.getEnvironment().clear();
      commandLine.getEnvironment().putAll(env);
-     commandLine.setPassParentEnvironment(myConfig.isPassParentEnvs());
+     commandLine.withParentEnvironmentType(myConfig.isPassParentEnvs() ? ParentEnvironmentType.SHELL : ParentEnvironmentType.NONE);
  
 -    buildPythonPath(commandLine, myConfig.isPassParentEnvs());
 +    buildPythonPath(project, commandLine, myConfig);
    }
  
    protected static void addCommonEnvironmentVariables(Map<String, String> env) {