From ca8074c8b5688b75c234599660331db6975b6878 Mon Sep 17 00:00:00 2001 From: Dmitry Trofimov Date: Thu, 7 Oct 2010 17:38:48 +0400 Subject: [PATCH 01/40] cosmetic --- python/helpers/pydev/pydevd_comm.py | 8 ++++---- .../jetbrains/python/debugger/PyDebuggerEvaluator.java | 4 +++- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/python/helpers/pydev/pydevd_comm.py b/python/helpers/pydev/pydevd_comm.py index 34e1b219b96d..31b448993cff 100644 --- a/python/helpers/pydev/pydevd_comm.py +++ b/python/helpers/pydev/pydevd_comm.py @@ -48,11 +48,11 @@ each command has a format: 120 CMD_GET_COMPLETIONS JAVA 500 series diagnostics/ok - 901 VERSION either Version string (1.0) Currently just used at startup - 902 RETURN either Depends on caller - + 501 VERSION either Version string (1.0) Currently just used at startup + 502 RETURN either Depends on caller - 900 series: errors - 501 ERROR either - This is reserved for unexpected errors. + 901 ERROR either - This is reserved for unexpected errors. * JAVA - remote debugger, the java end * PYDB - pydevd, the python end @@ -755,7 +755,7 @@ class InternalGetCompletions(InternalThreadCommand): except: exc = GetExceptionTracebackStr() sys.stderr.write('%s\n' % (exc,)) - cmd = dbg.cmdFactory.makeErrorMessage(self.sequence, "Error evaluating expression " + exc) + cmd = dbg.cmdFactory.makeErrorMessage(self.sequence, "Error getting completion " + exc) dbg.writer.addCommand(cmd) diff --git a/python/src/com/jetbrains/python/debugger/PyDebuggerEvaluator.java b/python/src/com/jetbrains/python/debugger/PyDebuggerEvaluator.java index d095b0ae7e91..f05ed85bb308 100644 --- a/python/src/com/jetbrains/python/debugger/PyDebuggerEvaluator.java +++ b/python/src/com/jetbrains/python/debugger/PyDebuggerEvaluator.java @@ -3,8 +3,10 @@ package com.jetbrains.python.debugger; import com.intellij.openapi.editor.Document; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.TextRange; +import com.intellij.xdebugger.XSourcePosition; import com.intellij.xdebugger.evaluation.XDebuggerEvaluator; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; public class PyDebuggerEvaluator extends XDebuggerEvaluator { @@ -18,7 +20,7 @@ public class PyDebuggerEvaluator extends XDebuggerEvaluator { } @Override - public void evaluate(@NotNull String expression, final XEvaluationCallback callback) { + public void evaluate(@NotNull String expression, XEvaluationCallback callback, @Nullable XSourcePosition expressionPosition) { expression = expression.trim(); if ("".equals(expression)) { callback.evaluated(NONE); From a51b8ba58b4a953bf5f7bec44b02d9c0b7fb7874 Mon Sep 17 00:00:00 2001 From: Dmitry Jemerov Date: Thu, 7 Oct 2010 19:07:22 +0400 Subject: [PATCH 02/40] enter PyClass in structure view by default (PY-1907) --- .../jetbrains/python/structureView/PyStructureViewModel.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/python/src/com/jetbrains/python/structureView/PyStructureViewModel.java b/python/src/com/jetbrains/python/structureView/PyStructureViewModel.java index 32b05f99117d..85a03ed28fb4 100644 --- a/python/src/com/jetbrains/python/structureView/PyStructureViewModel.java +++ b/python/src/com/jetbrains/python/structureView/PyStructureViewModel.java @@ -28,4 +28,9 @@ public class PyStructureViewModel extends StructureViewModelBase implements Stru public boolean isAlwaysLeaf(StructureViewTreeElement element) { return element.getValue() instanceof PyTargetExpression; } + + @Override + public boolean shouldEnterElement(Object element) { + return element instanceof PyClass; + } } From 7af9319cabc4c1378b9323475f43c2653db3124c Mon Sep 17 00:00:00 2001 From: Dmitry Jemerov Date: Fri, 8 Oct 2010 15:51:14 +0400 Subject: [PATCH 03/40] "dump psi to clipboard" is internal action --- python/src/META-INF/python-plugin-common.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/python/src/META-INF/python-plugin-common.xml b/python/src/META-INF/python-plugin-common.xml index 93f9a92322eb..ea400e8c6500 100644 --- a/python/src/META-INF/python-plugin-common.xml +++ b/python/src/META-INF/python-plugin-common.xml @@ -363,6 +363,7 @@ id="Devmode.DumpPsi" class="com.jetbrains.python.devmode.DumpPsiToClipboardAction" text="Dump PSI to clipboard" + internal="true" > From 8ed8bb2684b687100c142a58901a8e3225b1995b Mon Sep 17 00:00:00 2001 From: Dmitry Jemerov Date: Mon, 11 Oct 2010 14:11:24 +0400 Subject: [PATCH 04/40] python plugin depends on java --- python/pluginSrc/META-INF/plugin.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/python/pluginSrc/META-INF/plugin.xml b/python/pluginSrc/META-INF/plugin.xml index c69ad04b367c..26c2fa4b5501 100644 --- a/python/pluginSrc/META-INF/plugin.xml +++ b/python/pluginSrc/META-INF/plugin.xml @@ -8,6 +8,7 @@ Smart editing for Python scripts 2.6.2 com.intellij.modules.ultimate + com.intellij.modules.java org.jetbrains.plugins.yaml JetBrains, Keith Lea From a193c5ed261f6a511e2111a4f8b0d9a8d5cc6c9e Mon Sep 17 00:00:00 2001 From: Dmitry Jemerov Date: Mon, 11 Oct 2010 15:55:33 +0400 Subject: [PATCH 05/40] enter in subscription expression (PY-1992) --- .../src/com/jetbrains/python/editor/PythonEnterHandler.java | 3 ++- python/src/com/jetbrains/python/formatter/PyBlock.java | 3 ++- python/testSrc/com/jetbrains/python/PyEditingTest.java | 4 ++++ 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/python/src/com/jetbrains/python/editor/PythonEnterHandler.java b/python/src/com/jetbrains/python/editor/PythonEnterHandler.java index 28c5405b9954..ebe513774863 100644 --- a/python/src/com/jetbrains/python/editor/PythonEnterHandler.java +++ b/python/src/com/jetbrains/python/editor/PythonEnterHandler.java @@ -31,7 +31,8 @@ public class PythonEnterHandler implements EnterHandlerDelegate { PyArgumentList.class, PyParameterList.class, PyFunction.class, - PySliceExpression.class + PySliceExpression.class, + PySubscriptionExpression.class }; @Override diff --git a/python/src/com/jetbrains/python/formatter/PyBlock.java b/python/src/com/jetbrains/python/formatter/PyBlock.java index 38d213b37880..9d1bf5fb3f6e 100644 --- a/python/src/com/jetbrains/python/formatter/PyBlock.java +++ b/python/src/com/jetbrains/python/formatter/PyBlock.java @@ -46,7 +46,8 @@ public class PyBlock implements ASTBlock { PyElementTypes.PARAMETER_LIST, PyElementTypes.TUPLE_EXPRESSION, PyElementTypes.PARENTHESIZED_EXPRESSION, - PyElementTypes.SLICE_EXPRESSION); + PyElementTypes.SLICE_EXPRESSION, + PyElementTypes.SUBSCRIPTION_EXPRESSION); private static final TokenSet ourBrackets = TokenSet.create(PyTokenTypes.LPAR, PyTokenTypes.RPAR, PyTokenTypes.LBRACE, PyTokenTypes.RBRACE, diff --git a/python/testSrc/com/jetbrains/python/PyEditingTest.java b/python/testSrc/com/jetbrains/python/PyEditingTest.java index 60556d11e405..23ae43a15ad5 100644 --- a/python/testSrc/com/jetbrains/python/PyEditingTest.java +++ b/python/testSrc/com/jetbrains/python/PyEditingTest.java @@ -146,6 +146,10 @@ public class PyEditingTest extends PyLightFixtureTestCase { doTestEnter("a = some_list[slice_start:slice_end]", "a = some_list[\n slice_start:slice_end]"); } + public void testEnterInSubscriptionExpression() { // PY-1992 + doTestEnter("a = some_list[slice_start]", "a = some_list[\n slice_start]"); + } + private void doTestEnter(String before, final String after) { int pos = before.indexOf(""); before = before.replace("", ""); From ed1d69c5dc4aa8e59772a6334603b57bd8526a4e Mon Sep 17 00:00:00 2001 From: Dmitry Jemerov Date: Mon, 11 Oct 2010 19:07:36 +0400 Subject: [PATCH 06/40] update since/until; include file templates in plugin resources (PY-1803) --- python/build/build-plugin.xml | 5 +---- python/pluginSrc/META-INF/plugin.xml | 2 +- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/python/build/build-plugin.xml b/python/build/build-plugin.xml index bd723494de05..e9d212f8be4e 100644 --- a/python/build/build-plugin.xml +++ b/python/build/build-plugin.xml @@ -72,10 +72,6 @@ - - - - @@ -89,6 +85,7 @@ + diff --git a/python/pluginSrc/META-INF/plugin.xml b/python/pluginSrc/META-INF/plugin.xml index 26c2fa4b5501..6cbdc1bafc0c 100644 --- a/python/pluginSrc/META-INF/plugin.xml +++ b/python/pluginSrc/META-INF/plugin.xml @@ -4,7 +4,7 @@ Pythonid Python - + Smart editing for Python scripts 2.6.2 com.intellij.modules.ultimate From abb23f7e43c66fdb763a6129b9034179c5ef5f2e Mon Sep 17 00:00:00 2001 From: Dmitry Jemerov Date: Mon, 11 Oct 2010 19:12:59 +0400 Subject: [PATCH 07/40] advance version number --- python/pluginSrc/META-INF/plugin.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/pluginSrc/META-INF/plugin.xml b/python/pluginSrc/META-INF/plugin.xml index 6cbdc1bafc0c..8a3389031e74 100644 --- a/python/pluginSrc/META-INF/plugin.xml +++ b/python/pluginSrc/META-INF/plugin.xml @@ -6,7 +6,7 @@ Python Smart editing for Python scripts - 2.6.2 + 2.6.3 com.intellij.modules.ultimate com.intellij.modules.java org.jetbrains.plugins.yaml From 6dcdb6715518ea6a8ef016e04fc59044af102d8e Mon Sep 17 00:00:00 2001 From: Dmitry Jemerov Date: Mon, 11 Oct 2010 19:30:20 +0400 Subject: [PATCH 08/40] mention Django in module type description --- python/src/com/jetbrains/python/PythonModuleTypeBase.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/src/com/jetbrains/python/PythonModuleTypeBase.java b/python/src/com/jetbrains/python/PythonModuleTypeBase.java index c9500db06d15..4199f4b36aa5 100644 --- a/python/src/com/jetbrains/python/PythonModuleTypeBase.java +++ b/python/src/com/jetbrains/python/PythonModuleTypeBase.java @@ -25,7 +25,7 @@ public abstract class PythonModuleTypeBase extends Modu } public String getDescription() { - return "Provides facilities for developing Python applications"; + return "Provides facilities for developing Python and Django applications"; } public Icon getBigIcon() { From 0c8e941d65725b5da89af70bbe1b6aeec40b2769 Mon Sep 17 00:00:00 2001 From: Dmitry Jemerov Date: Mon, 11 Oct 2010 20:25:59 +0400 Subject: [PATCH 09/40] we don't need to have any specific file to check if Django is importable, and also don't need to cache the availability --- .../python/psi/resolve/ResolveImportUtil.java | 27 ++++++++++++++----- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/python/src/com/jetbrains/python/psi/resolve/ResolveImportUtil.java b/python/src/com/jetbrains/python/psi/resolve/ResolveImportUtil.java index a6bca3ecc8f1..1bcca02b1e97 100644 --- a/python/src/com/jetbrains/python/psi/resolve/ResolveImportUtil.java +++ b/python/src/com/jetbrains/python/psi/resolve/ResolveImportUtil.java @@ -299,6 +299,19 @@ public class ResolveImportUtil { return visitor.results; } + @NotNull + public static List resolveModulesInRoots(@NotNull Module module, @NotNull PyQualifiedName moduleQualifiedName) { + PythonPathCache cache = PythonModulePathCache.getInstance(module); + final List cachedResults = cache.get(moduleQualifiedName); + if (cachedResults != null) { + return cachedResults; + } + ResolveInRootVisitor visitor = new ResolveInRootVisitor(moduleQualifiedName, PsiManager.getInstance(module.getProject()), null); + visitRoots(module, visitor); + cache.put(moduleQualifiedName, visitor.results); + return visitor.results; + } + // TODO: rewrite using resolveImportReference /** @@ -478,22 +491,22 @@ public class ResolveImportUtil { } static class ResolveInRootVisitor implements RootVisitor { - final PsiFile foothold_file; + final PsiFile myFootholdFile; final @NotNull PyQualifiedName qualifiedName; final @NotNull PsiManager psiManager; final List results = new ArrayList(); - public ResolveInRootVisitor(@NotNull PyQualifiedName qName, @NotNull PsiManager psiManager, PsiFile foothold_file) { + public ResolveInRootVisitor(@NotNull PyQualifiedName qName, @NotNull PsiManager psiManager, @Nullable PsiFile foothold_file) { this.qualifiedName = qName; this.psiManager = psiManager; - this.foothold_file = foothold_file; + myFootholdFile = foothold_file; } public boolean visitRoot(final VirtualFile root) { if (!root.isValid()) { return true; } - PsiElement module = resolveInRoot(root, qualifiedName, psiManager, foothold_file); + PsiElement module = resolveInRoot(root, qualifiedName, psiManager, myFootholdFile); if (module != null) { results.add(module); } @@ -502,7 +515,7 @@ public class ResolveImportUtil { } @Nullable - private static PsiElement resolveInRoot(VirtualFile root, PyQualifiedName qualifiedName, PsiManager psiManager, PsiFile foothold_file) { + private static PsiElement resolveInRoot(VirtualFile root, PyQualifiedName qualifiedName, PsiManager psiManager, @Nullable PsiFile foothold_file) { PsiElement module = root.isDirectory() ? psiManager.findDirectory(root) : psiManager.findFile(root); for (String component : qualifiedName.getComponents()) { if (component == null) { @@ -530,7 +543,7 @@ public class ResolveImportUtil { */ @Nullable public static PsiElement resolveChild(@Nullable final PsiElement parent, @NotNull final String referencedName, - final PsiFile containingFile, @Nullable VirtualFile root, boolean fileOnly) { + @Nullable final PsiFile containingFile, @Nullable VirtualFile root, boolean fileOnly) { PsiDirectory dir = null; PsiElement ret = null; PsiElement possible_ret = null; @@ -569,7 +582,7 @@ public class ResolveImportUtil { } @Nullable - private static PsiElement resolveInDirectory(final String referencedName, final PsiFile containingFile, + private static PsiElement resolveInDirectory(final String referencedName, @Nullable final PsiFile containingFile, final PsiDirectory dir, @Nullable VirtualFile root, boolean isFileOnly) { if (referencedName == null) return null; final PsiElement module = findModuleInDir(dir, referencedName); From b031cb156e1ef3e59ef23193a2430f7baab5ea0d Mon Sep 17 00:00:00 2001 From: Dmitry Trofimov Date: Fri, 8 Oct 2010 21:47:22 +0400 Subject: [PATCH 10/40] fixed run sh syntax --- python/build/pycharm.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/build/pycharm.sh b/python/build/pycharm.sh index 44f1a9e86824..93d3745e4f86 100644 --- a/python/build/pycharm.sh +++ b/python/build/pycharm.sh @@ -83,7 +83,7 @@ if [ -z "$PYCHARM_VM_OPTIONS" ]; then fi # isEap -if ["@@isEap@@" -eq "true" ] +if ["@@isEap@@" -eq "true" ]; then $AGENT="-agentlib:yjpagent$BITS=disablej2ee,sessionname=pycharm" fi From 970765fcdebf2f48d8650bd2ca37babd3138588b Mon Sep 17 00:00:00 2001 From: Dmitry Trofimov Date: Tue, 12 Oct 2010 15:27:12 +0400 Subject: [PATCH 11/40] reindex django templates on enabling django facet --- python/python-ide.iml | 1 + 1 file changed, 1 insertion(+) diff --git a/python/python-ide.iml b/python/python-ide.iml index 7216109fe347..40af0d8cc13f 100644 --- a/python/python-ide.iml +++ b/python/python-ide.iml @@ -17,6 +17,7 @@ + From c13622a53a94668590ada42886783dccbe47e7bc Mon Sep 17 00:00:00 2001 From: Oleg Shpynov Date: Tue, 12 Oct 2010 16:11:42 +0400 Subject: [PATCH 12/40] PY-2102 Extract method fails --- .../codeFragment/PyCodeFragmentUtil.java | 5 +++++ .../codeInsight/codefragment/raise2102.test | 17 +++++++++++++++++ .../python/refactoring/PyCodeFragmentTest.java | 5 +++++ 3 files changed, 27 insertions(+) create mode 100644 python/testData/codeInsight/codefragment/raise2102.test diff --git a/python/src/com/jetbrains/python/codeInsight/codeFragment/PyCodeFragmentUtil.java b/python/src/com/jetbrains/python/codeInsight/codeFragment/PyCodeFragmentUtil.java index 9ee79e05469c..c834b116fcf4 100644 --- a/python/src/com/jetbrains/python/codeInsight/codeFragment/PyCodeFragmentUtil.java +++ b/python/src/com/jetbrains/python/codeInsight/codeFragment/PyCodeFragmentUtil.java @@ -7,6 +7,7 @@ import com.intellij.codeInsight.codeFragment.Position; import com.intellij.codeInsight.controlflow.ConditionalInstruction; import com.intellij.codeInsight.controlflow.Instruction; import com.intellij.psi.PsiElement; +import com.intellij.psi.util.PsiTreeUtil; import com.intellij.util.containers.HashSet; import com.jetbrains.python.PyBundle; import com.jetbrains.python.codeInsight.controlflow.ScopeOwner; @@ -83,6 +84,10 @@ public class PyCodeFragmentUtil { if (nextElement instanceof PyExceptPart){ continue; } + // We allow raise statements in code + if (nextElement == null && PsiTreeUtil.getParentOfType(element, PyRaiseStatement.class) != null){ + continue; + } if (!CodeFragmentUtil.elementFit(nextElement, start, end)){ outerInstructions.add(next); } diff --git a/python/testData/codeInsight/codefragment/raise2102.test b/python/testData/codeInsight/codefragment/raise2102.test new file mode 100644 index 000000000000..a9f49a6fdb23 --- /dev/null +++ b/python/testData/codeInsight/codefragment/raise2102.test @@ -0,0 +1,17 @@ +foo() + +for i in range(l): + if foo: + if tag is None: + if bar: + do + else: + if baz: + raise ValueError(i) + else: + bzzzz + +bar() + +In: +Out: \ No newline at end of file diff --git a/python/testSrc/com/jetbrains/python/refactoring/PyCodeFragmentTest.java b/python/testSrc/com/jetbrains/python/refactoring/PyCodeFragmentTest.java index 353069f54939..8f46ff540429 100644 --- a/python/testSrc/com/jetbrains/python/refactoring/PyCodeFragmentTest.java +++ b/python/testSrc/com/jetbrains/python/refactoring/PyCodeFragmentTest.java @@ -159,5 +159,10 @@ public class PyCodeFragmentTest extends LightMarkedTestCase { public void testForIfReturn() throws Exception { doTest(); } + + public void testRaise2102() throws Exception { + doTest(); + } + } From 2a74a61b8158974f4f4dd033b2404cfdff5891cd Mon Sep 17 00:00:00 2001 From: Dmitry Jemerov Date: Tue, 12 Oct 2010 18:25:46 +0400 Subject: [PATCH 13/40] __Classobj is a PyCharm internal thing, don't expose it via Override feature (PY-2098) --- .../codeInsight/override/PyMethodMember.java | 4 +++ .../override/PyOverrideImplementUtil.java | 35 +++++++++++-------- 2 files changed, 24 insertions(+), 15 deletions(-) diff --git a/python/src/com/jetbrains/python/codeInsight/override/PyMethodMember.java b/python/src/com/jetbrains/python/codeInsight/override/PyMethodMember.java index b585b562c6fd..2a9de0f75630 100644 --- a/python/src/com/jetbrains/python/codeInsight/override/PyMethodMember.java +++ b/python/src/com/jetbrains/python/codeInsight/override/PyMethodMember.java @@ -6,6 +6,7 @@ import com.intellij.codeInsight.generation.PsiElementMemberChooserObject; import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.ui.SimpleColoredComponent; +import com.jetbrains.python.PyNames; import com.jetbrains.python.psi.PyClass; import com.jetbrains.python.psi.PyElement; import com.jetbrains.python.psi.PyFunction; @@ -21,6 +22,9 @@ public class PyMethodMember extends PsiElementMemberChooserObject implements Cla if (element instanceof PyFunction) { return element.getName() + ((PyFunction)element).getParameterList().getText(); } + if (element instanceof PyClass && PyNames.FAKE_OLD_BASE.equals(element.getName())) { + return ""; + } return element.getName(); } diff --git a/python/src/com/jetbrains/python/codeInsight/override/PyOverrideImplementUtil.java b/python/src/com/jetbrains/python/codeInsight/override/PyOverrideImplementUtil.java index 130502b1d72c..213b96b78550 100644 --- a/python/src/com/jetbrains/python/codeInsight/override/PyOverrideImplementUtil.java +++ b/python/src/com/jetbrains/python/codeInsight/override/PyOverrideImplementUtil.java @@ -169,24 +169,29 @@ public class PyOverrideImplementUtil { }, ArrayUtil.EMPTY_STRING_ARRAY); int startIndex = 0; - if (baseFunction.getReturnType() != PyNoneType.INSTANCE) { - statementBody.append("return "); - } - if (baseClass.isNewStyleClass()) { - statementBody.append(PyNames.SUPER); - statementBody.append("("); - final LanguageLevel langLevel = ((PyFile)pyClass.getContainingFile()).getLanguageLevel(); - if (!langLevel.isPy3K()) { - statementBody.append(pyClass.getName()).append(", ").append(PyUtil.getFirstParameterName(baseFunction)); - } - statementBody.append(").").append(baseFunction.getName()).append("("); - startIndex = 1; + if (PyNames.FAKE_OLD_BASE.equals(baseFunction.getContainingClass().getName())) { + statementBody.append("pass"); } else { - statementBody.append(baseClass.getName()).append(".").append(baseFunction.getName()).append("("); + if (baseFunction.getReturnType() != PyNoneType.INSTANCE) { + statementBody.append("return "); + } + if (baseClass.isNewStyleClass()) { + statementBody.append(PyNames.SUPER); + statementBody.append("("); + final LanguageLevel langLevel = ((PyFile)pyClass.getContainingFile()).getLanguageLevel(); + if (!langLevel.isPy3K()) { + statementBody.append(pyClass.getName()).append(", ").append(PyUtil.getFirstParameterName(baseFunction)); + } + statementBody.append(").").append(baseFunction.getName()).append("("); + startIndex = 1; + } + else { + statementBody.append(baseClass.getName()).append(".").append(baseFunction.getName()).append("("); + } + statementBody.append(StringUtil.join(paramTexts, startIndex, paramTexts.length, ", ")); + statementBody.append(")"); } - statementBody.append(StringUtil.join(paramTexts, startIndex, paramTexts.length, ", ")); - statementBody.append(")"); pyFunctionBuilder.statement(statementBody.toString()); return pyFunctionBuilder; From 583262d701f8358aa23dae619a77d6c275d6f10f Mon Sep 17 00:00:00 2001 From: Dmitry Jemerov Date: Tue, 12 Oct 2010 18:42:53 +0400 Subject: [PATCH 14/40] fix path validation in Extract Superclass --- .../classes/extractSuperclass/PyExtractSuperclassDialog.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/python/src/com/jetbrains/python/refactoring/classes/extractSuperclass/PyExtractSuperclassDialog.java b/python/src/com/jetbrains/python/refactoring/classes/extractSuperclass/PyExtractSuperclassDialog.java index e5a7b5ae6b29..17533957438f 100644 --- a/python/src/com/jetbrains/python/refactoring/classes/extractSuperclass/PyExtractSuperclassDialog.java +++ b/python/src/com/jetbrains/python/refactoring/classes/extractSuperclass/PyExtractSuperclassDialog.java @@ -8,6 +8,7 @@ import com.intellij.openapi.roots.ProjectRootManager; import com.intellij.openapi.ui.TextComponentAccessor; import com.intellij.openapi.ui.TextFieldWithBrowseButton; import com.intellij.openapi.util.io.FileUtil; +import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.refactoring.RefactoringBundle; import com.intellij.refactoring.classMembers.AbstractUsesDependencyMemberInfoModel; @@ -69,9 +70,9 @@ public class PyExtractSuperclassDialog extends UpDirectedMembersMovingDialog { } boolean found_root = false; try { - String target_dir = new File(myTargetDirField.getText()).getCanonicalPath(); + String target_dir = FileUtil.toSystemIndependentName(new File(myTargetDirField.getText()).getCanonicalPath()); for (VirtualFile file : ProjectRootManager.getInstance(myClass.getProject()).getContentRoots()) { - if (target_dir.startsWith(file.getPath())) { + if (StringUtil.startsWithIgnoreCase(target_dir, file.getPath())) { found_root = true; break; } From 040fc132cbb63a0f65c7a3409989d90183db4ea9 Mon Sep 17 00:00:00 2001 From: Dennis Ushakov Date: Tue, 12 Oct 2010 19:10:22 +0400 Subject: [PATCH 15/40] do not move class comments --- python/src/com/jetbrains/python/psi/PyUtil.java | 3 --- .../refactoring/pullup/withMultilineComments.after.py | 11 +++++------ 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/python/src/com/jetbrains/python/psi/PyUtil.java b/python/src/com/jetbrains/python/psi/PyUtil.java index 857162d1ff13..21cc4dd80bf1 100644 --- a/python/src/com/jetbrains/python/psi/PyUtil.java +++ b/python/src/com/jetbrains/python/psi/PyUtil.java @@ -74,9 +74,6 @@ public class PyUtil { } seeker = seeker.getPrevSibling(); } - if (seeker instanceof PyExpressionStatement && seeker.getFirstChild() instanceof PyStringLiteralExpression) { - comments.add(seeker); - } return comments; } diff --git a/python/testData/refactoring/pullup/withMultilineComments.after.py b/python/testData/refactoring/pullup/withMultilineComments.after.py index e1a0f1a49780..3780dec0eb33 100644 --- a/python/testData/refactoring/pullup/withMultilineComments.after.py +++ b/python/testData/refactoring/pullup/withMultilineComments.after.py @@ -2,13 +2,12 @@ class Foo: def foo(self): print("a") - ''' - this is boo - very long boo - ''' - def boo(self): print "rrrrr" class Boo(Foo): - pass + ''' + this is boo + very long boo + ''' + From e540bd45e5d9659e8744544d91de475a52eda749 Mon Sep 17 00:00:00 2001 From: Dmitry Trofimov Date: Tue, 12 Oct 2010 20:17:04 +0400 Subject: [PATCH 16/40] fixed eval of compound global vars (PY-2101) --- python/helpers/pydev/pydevd_vars.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/python/helpers/pydev/pydevd_vars.py b/python/helpers/pydev/pydevd_vars.py index e4bef21924e2..c2e141a2a3ee 100644 --- a/python/helpers/pydev/pydevd_vars.py +++ b/python/helpers/pydev/pydevd_vars.py @@ -325,6 +325,11 @@ def resolveCompoundVariable(thread_id, frame_id, scope, attrs): del attrList[0] # globals are special, and they get a single dummy unused attribute else: var = frame.f_locals + type, _typeName, resolver = getType(var) + try: + resolver.resolve(var, attrs[0]) + except: + var = frame.f_globals for k in attrList: type, _typeName, resolver = getType(var) From 54fc232d91933ae3657b35c24654370130d3ba44 Mon Sep 17 00:00:00 2001 From: Dmitry Jemerov Date: Wed, 13 Oct 2010 17:09:52 +0400 Subject: [PATCH 17/40] include pycharm.sh instead of idea.sh in PyCharm Mac dmg --- python/build/pycharm_build.gant | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/python/build/pycharm_build.gant b/python/build/pycharm_build.gant index 3cf89800e612..0e4f7c529900 100644 --- a/python/build/pycharm_build.gant +++ b/python/build/pycharm_build.gant @@ -486,10 +486,15 @@ def layoutMac(Map args, String target) { layout(target) { dir("bin") { fileset(dir: "$home/community/bin/mac") - fileset(dir: "$home/community/bin/nix") + fileset(dir: "$home/community/bin/nix") { + exclude(name: "idea.sh") + } fileset(dir: "$home/bin") { include(name: "*.jnilib") } + fileset(dir: "$home/python/build") { + include(name: "pycharm.sh") + } } dir("lib") { fileset(dir: "$home/community/build/conf/mac/lib") From 23b0caa50d99f562d464050a34c6daa173e5bcfa Mon Sep 17 00:00:00 2001 From: Dmitry Trofimov Date: Tue, 12 Oct 2010 20:43:16 +0400 Subject: [PATCH 18/40] removed ; --- python/helpers/pydev/pydevd_vars.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/helpers/pydev/pydevd_vars.py b/python/helpers/pydev/pydevd_vars.py index c2e141a2a3ee..52317b188934 100644 --- a/python/helpers/pydev/pydevd_vars.py +++ b/python/helpers/pydev/pydevd_vars.py @@ -428,7 +428,7 @@ def changeAttrExpression(thread_id, frame_id, attr, expression): #default way (only works for changing it in the topmost frame) result = eval(expression, frame.f_globals, frame.f_locals) exec('%s=%s' % (attr, expression), frame.f_globals, frame.f_locals) - return result; + return result except Exception: From 7086d78e610e5333aa86f42ad0bec10c200e3ccb Mon Sep 17 00:00:00 2001 From: Dmitry Trofimov Date: Thu, 14 Oct 2010 17:29:18 +0400 Subject: [PATCH 19/40] added runnerw.exe to python plugin --- python/build/build-plugin.xml | 327 ++++++++++++++------------- python/pluginSrc/META-INF/plugin.xml | 4 + 2 files changed, 169 insertions(+), 162 deletions(-) diff --git a/python/build/build-plugin.xml b/python/build/build-plugin.xml index e9d212f8be4e..479a952d5402 100644 --- a/python/build/build-plugin.xml +++ b/python/build/build-plugin.xml @@ -1,194 +1,197 @@ - - + + - - + + - - + + - + - - - - - - + + + + + + - - - + + + - - - - - + + + + + - - + + - - - - - - - - - - - + + + + + + + + + + + - - - - - - - - - - - + + + + + + + + + + + - - - - - + + + + + - - - - - + + + + + - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + - - - + + + - - - - - - - - - + + + + + + + + + - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + - - - - - - - - + + + + + + + + - - - - - - - - - + + + + + + + + + - - + + - - - + + + - - - - + + + + - - - - + + + + - - + + - + + + + + + + + + + + + + + + --> - + - + - - - - + + + + - + \ No newline at end of file diff --git a/python/pluginSrc/META-INF/plugin.xml b/python/pluginSrc/META-INF/plugin.xml index 8a3389031e74..e4172461b0ed 100644 --- a/python/pluginSrc/META-INF/plugin.xml +++ b/python/pluginSrc/META-INF/plugin.xml @@ -23,6 +23,8 @@ + @@ -43,4 +45,6 @@ + + From 165702aa457121bb55f962bffe78821ca00117e0 Mon Sep 17 00:00:00 2001 From: Dmitry Trofimov Date: Thu, 14 Oct 2010 22:27:51 +0400 Subject: [PATCH 20/40] django template parameters resolve in case of locals() as argument of render function (PY-1982) --- .../python/psi/impl/PyReferenceImpl.java | 165 +----------------- 1 file changed, 4 insertions(+), 161 deletions(-) diff --git a/python/src/com/jetbrains/python/psi/impl/PyReferenceImpl.java b/python/src/com/jetbrains/python/psi/impl/PyReferenceImpl.java index 5db0baeb51cb..dcf765ce4dbd 100644 --- a/python/src/com/jetbrains/python/psi/impl/PyReferenceImpl.java +++ b/python/src/com/jetbrains/python/psi/impl/PyReferenceImpl.java @@ -1,5 +1,6 @@ package com.jetbrains.python.psi.impl; +import com.google.common.collect.Lists; import com.intellij.codeInsight.lookup.LookupElement; import com.intellij.codeInsight.lookup.LookupElementBuilder; import com.intellij.lang.ASTNode; @@ -15,11 +16,11 @@ import com.intellij.util.Icons; import com.intellij.util.IncorrectOperationException; import com.intellij.util.ProcessingContext; import com.intellij.util.containers.SortedList; +import com.jetbrains.django.util.PythonDataflowUtil; import com.jetbrains.python.PyNames; import com.jetbrains.python.codeInsight.controlflow.ScopeOwner; import com.jetbrains.python.psi.*; import com.jetbrains.python.psi.resolve.*; -import com.jetbrains.python.psi.search.PySuperMethodsSearch; import com.jetbrains.python.psi.types.PyModuleType; import com.jetbrains.python.psi.types.PyType; import com.jetbrains.python.psi.types.TypeEvalContext; @@ -351,7 +352,7 @@ public class PyReferenceImpl implements PsiReferenceEx, PsiPolyVariantReference @NotNull public Object[] getVariants() { - final List ret = new ArrayList(); + final List ret = Lists.newArrayList(); // Use real context here to enable correct completion and resolve in case of PyExpressionCodeFragment!!! final PsiElement realContext = PyPsiUtils.getRealContext(myElement); @@ -364,24 +365,7 @@ public class PyReferenceImpl implements PsiReferenceEx, PsiPolyVariantReference PyResolveUtil.scanOuterContext(processor, realContext); // possible names from around us at call time // in a call, include function's arg names - PyCallExpression call_expr = PsiTreeUtil.getParentOfType(myElement, PyCallExpression.class); - if (call_expr != null) { - PyExpression callee = call_expr.getCallee(); - if (callee instanceof PyReferenceExpression) { - if (PsiTreeUtil.getParentOfType(myElement, PyKeywordArgument.class) == null) { - PsiElement def = ((PyReferenceExpression)callee).getReference().resolve(); - if (def instanceof PyFunction) { - addKeywordArgumentVariants((PyFunction)def, ret); - } - else if (def instanceof PyClass) { - PyFunction init = ((PyClass)def).findMethodByName(PyNames.INIT, true); // search in superclasses - if (init != null) { - addKeywordArgumentVariants(init, ret); - } - } - } - } - } + PythonDataflowUtil.collectFunctionArgNames(myElement, ret); // scan all "import *" and include names provided by them CollectProcessor collect_proc = new CollectProcessor(IS_STAR_IMPORT); @@ -428,147 +412,6 @@ public class PyReferenceImpl implements PsiReferenceEx, PsiPolyVariantReference return ret.toArray(); } - private static void addKeywordArgumentVariants(PyFunction def, final List ret) { - addKeywordArgumentVariants(def, ret, new HashSet()); - } - - private static void addKeywordArgumentVariants(PyFunction def, List ret, Collection visited) { - if (visited.contains(def)) { - return; - } - visited.add(def); - final Set flags = def.getContainingClass() != null ? PyUtil.detectDecorationsAndWrappersOf(def) : null; - final KwArgParameterCollector collector = new KwArgParameterCollector(flags, ret); - def.getParameterList().acceptChildren(collector); - if (collector.hasKwArgs()) { - KwArgFromStatementCallCollector fromStatementCallCollector = new KwArgFromStatementCallCollector(ret, collector.getKwArgs()); - def.getStatementList().acceptChildren(fromStatementCallCollector); - - //if (collector.hasOnlySelfAndKwArgs()) { - // nothing interesting besides self and **kwargs, let's look at superclass (PY-778) - if (fromStatementCallCollector.isKwArgsTransit()) { - - final PsiElement superMethod = PySuperMethodsSearch.search(def).findFirst(); - if (superMethod instanceof PyFunction) { - addKeywordArgumentVariants((PyFunction)superMethod, ret, visited); - } - } - } -//} - } - - private static class KwArgParameterCollector extends PyElementVisitor { - private int myCount; - private final Set myFlags; - private final List myRet; - private boolean myHasSelf = false; - private boolean myHasKwArgs = false; - private PyParameter kwArgsParam = null; - - public KwArgParameterCollector(Set flags, List ret) { - myFlags = flags; - myRet = ret; - } - - @Override - public void visitPyParameter(PyParameter par) { - myCount++; - if (myCount == 1 && myFlags != null && !myFlags.contains(PyFunction.Flag.STATICMETHOD)) { - myHasSelf = true; - return; - } - PyNamedParameter namedParam = par.getAsNamed(); - assert namedParam != null; - if (!namedParam.isKeywordContainer() && !namedParam.isPositionalContainer()) { - final LookupElement item = PyUtil.createNamedParameterLookup(namedParam.getName()); - myRet.add(item); - } - else if (namedParam.isKeywordContainer()) { - myHasKwArgs = true; - kwArgsParam = namedParam; - } - } - - public PyParameter getKwArgs() { - return kwArgsParam; - } - - public boolean hasKwArgs() { - return myHasKwArgs; - } - - public boolean hasOnlySelfAndKwArgs() { - return myCount == 2 && myHasSelf && myHasKwArgs; - } - } - - private static class KwArgFromStatementCallCollector extends PyElementVisitor { - private final List myRet; - private final PyParameter myKwArgs; - private boolean kwArgsTransit = true; - - public KwArgFromStatementCallCollector(List ret, @NotNull PyParameter kwArgs) { - myRet = ret; - this.myKwArgs = kwArgs; - } - - @Override - public void visitPyElement(PyElement node) { - node.acceptChildren(this); - } - - @Override - public void visitPySubscriptionExpression(PySubscriptionExpression node) { - String operandName = node.getOperand().getName(); - processGet(operandName, node.getIndexExpression()); - } - - @Override - public void visitPyCallExpression(PyCallExpression node) { - if (node.isCalleeText("pop", "get", "getattr")) { - PyReferenceExpression child = PsiTreeUtil.getChildOfType(node.getCallee(), PyReferenceExpression.class); - if (child != null) { - String operandName = child.getName(); - if (node.getArguments().length > 0) { - PyExpression argument = node.getArguments()[0]; - processGet(operandName, argument); - } - } - } - else if (node.isCalleeText("__init__")) { - kwArgsTransit = false; - for (PyExpression e : node.getArguments()) { - if (e instanceof PyStarArgument) { - PyStarArgument kw = (PyStarArgument)e; - if (Comparing.equal(myKwArgs.getName(), kw.getFirstChild().getNextSibling().getText())) { - kwArgsTransit = true; - break; - } - } - } - } - super.visitPyCallExpression(node); - } - - private void processGet(String operandName, PyExpression argument) { - if (Comparing.equal(myKwArgs.getName(), operandName) && - argument instanceof PyStringLiteralExpression) { - String name = ((PyStringLiteralExpression)argument).getStringValue(); - if (PyUtil.isPythonIdentifier(name)) { - myRet.add(PyUtil.createNamedParameterLookup(name)); - } - } - } - - /** - * is name of kwargs parameter the same as transmitted to __init__ call - * @return - */ - public boolean isKwArgsTransit() { - return kwArgsTransit; - } - } - public boolean isSoft() { return false; } From 558a59299d5a582dfff48932e28c29a08265be3d Mon Sep 17 00:00:00 2001 From: Dmitry Trofimov Date: Thu, 14 Oct 2010 22:36:47 +0400 Subject: [PATCH 21/40] fixed resolve of django paramters in case of locals() --- .../com/jetbrains/python/psi/resolve/VariantsProcessor.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/python/src/com/jetbrains/python/psi/resolve/VariantsProcessor.java b/python/src/com/jetbrains/python/psi/resolve/VariantsProcessor.java index a7b494dab34b..9045d0cc0c6e 100644 --- a/python/src/com/jetbrains/python/psi/resolve/VariantsProcessor.java +++ b/python/src/com/jetbrains/python/psi/resolve/VariantsProcessor.java @@ -96,7 +96,7 @@ public class VariantsProcessor implements PsiScopeProcessor { PyReferenceExpression expr = (PyReferenceExpression)element; String referencedName = expr.getReferencedName(); if (nameIsAcceptable(referencedName)) { - myVariants.put(referencedName, setupItem(LookupElementBuilder.create(referencedName))); + myVariants.put(referencedName, setupItem(LookupElementBuilder.create(expr, referencedName))); } } else if (element instanceof NameDefiner) { @@ -123,7 +123,7 @@ public class VariantsProcessor implements PsiScopeProcessor { // things like PyTargetExpression cannot have a general icon, but here we only have variables if (icon == null) icon = Icons.VARIABLE_ICON; if (referencedName != null && nameIsAcceptable(referencedName)) { - LookupElementBuilder lookupItem = setupItem(LookupElementBuilder.create(referencedName).setIcon(icon)); + LookupElementBuilder lookupItem = setupItem(LookupElementBuilder.create(expr, referencedName).setIcon(icon)); if (definer instanceof PyImportElement) { // set notice to imported module name if needed PsiElement maybeFromImport = definer.getParent(); if (maybeFromImport instanceof PyFromImportStatement) { From f9c8bbdfd5c789dedbf10efd52e4643262e6f2d8 Mon Sep 17 00:00:00 2001 From: anna Date: Mon, 18 Oct 2010 12:54:50 +0400 Subject: [PATCH 22/40] help topics for sdks (IDEA-59895 ) --- python/src/com/jetbrains/python/sdk/PythonSdkType.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/python/src/com/jetbrains/python/sdk/PythonSdkType.java b/python/src/com/jetbrains/python/sdk/PythonSdkType.java index 6d5f1c11ed35..99e713e801f0 100644 --- a/python/src/com/jetbrains/python/sdk/PythonSdkType.java +++ b/python/src/com/jetbrains/python/sdk/PythonSdkType.java @@ -78,6 +78,12 @@ public class PythonSdkType extends SdkType { return PythonFileType.INSTANCE.getIcon(); } + @NotNull + @Override + public String getHelpTopic() { + return "reference.project.structure.sdk.python"; + } + public Icon getIconForAddAction() { return PythonFileType.INSTANCE.getIcon(); } From 0f97299a3bd50cda81412607dc577e4e53511537 Mon Sep 17 00:00:00 2001 From: Dmitry Trofimov Date: Fri, 15 Oct 2010 17:06:01 +0400 Subject: [PATCH 23/40] fixed extra } in js django (PY-2095) --- python/src/META-INF/python-plugin-common.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/src/META-INF/python-plugin-common.xml b/python/src/META-INF/python-plugin-common.xml index ea400e8c6500..c473e2182e45 100644 --- a/python/src/META-INF/python-plugin-common.xml +++ b/python/src/META-INF/python-plugin-common.xml @@ -41,7 +41,7 @@ serviceImplementation="com.jetbrains.python.psi.impl.PyElementGeneratorImpl"/> - + From 8f70534751227d3bb92bf1740c6483f9d848e79b Mon Sep 17 00:00:00 2001 From: Dmitry Trofimov Date: Mon, 18 Oct 2010 16:01:55 +0400 Subject: [PATCH 24/40] missing space added --- python/build/pycharm.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/build/pycharm.sh b/python/build/pycharm.sh index 93d3745e4f86..04415d96db96 100644 --- a/python/build/pycharm.sh +++ b/python/build/pycharm.sh @@ -83,7 +83,7 @@ if [ -z "$PYCHARM_VM_OPTIONS" ]; then fi # isEap -if ["@@isEap@@" -eq "true" ]; then +if [ "@@isEap@@" -eq "true" ]; then $AGENT="-agentlib:yjpagent$BITS=disablej2ee,sessionname=pycharm" fi From 2cd8a047a47538dbbc733fbbc61b4e04fe2650b0 Mon Sep 17 00:00:00 2001 From: Dmitry Trofimov Date: Mon, 18 Oct 2010 17:12:11 +0400 Subject: [PATCH 25/40] added completion to urls.py view reference string literals(PY-1051) --- python/src/META-INF/python-plugin-common.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/python/src/META-INF/python-plugin-common.xml b/python/src/META-INF/python-plugin-common.xml index c473e2182e45..5ad33c22ebac 100644 --- a/python/src/META-INF/python-plugin-common.xml +++ b/python/src/META-INF/python-plugin-common.xml @@ -274,6 +274,8 @@ + + From d79c67c7ef1fe72949e9eabaa9cd9c5430bc82a6 Mon Sep 17 00:00:00 2001 From: Dmitry Trofimov Date: Mon, 18 Oct 2010 20:11:10 +0400 Subject: [PATCH 26/40] buildout icon for buildout cfg file type --- .../jetbrains/python/buildout/BuildoutConfigurable.java | 2 +- .../com/jetbrains/python/buildout/BuildoutFacetType.java | 7 ++----- .../python/buildout/config/BuildoutCfgFileType.java | 4 ++-- 3 files changed, 5 insertions(+), 8 deletions(-) diff --git a/python/src/com/jetbrains/python/buildout/BuildoutConfigurable.java b/python/src/com/jetbrains/python/buildout/BuildoutConfigurable.java index 657d6dc0d5eb..e4c6626a8321 100644 --- a/python/src/com/jetbrains/python/buildout/BuildoutConfigurable.java +++ b/python/src/com/jetbrains/python/buildout/BuildoutConfigurable.java @@ -80,7 +80,7 @@ public class BuildoutConfigurable implements Configurable, NonDefaultProjectConf @Override public Icon getIcon() { - return BuildoutFacetType.ourIcon; + return BuildoutFacetType.BUILDOUT_ICON; } @Override diff --git a/python/src/com/jetbrains/python/buildout/BuildoutFacetType.java b/python/src/com/jetbrains/python/buildout/BuildoutFacetType.java index 19eafd93a224..d999e0fa539b 100644 --- a/python/src/com/jetbrains/python/buildout/BuildoutFacetType.java +++ b/python/src/com/jetbrains/python/buildout/BuildoutFacetType.java @@ -4,11 +4,8 @@ import com.intellij.facet.Facet; import com.intellij.facet.FacetType; import com.intellij.facet.FacetTypeId; import com.intellij.facet.FacetTypeRegistry; -import com.intellij.ide.DataManager; -import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.module.Module; import com.intellij.openapi.module.ModuleType; -import com.intellij.openapi.project.Project; import com.intellij.openapi.util.IconLoader; import com.jetbrains.python.PythonModuleTypeBase; import org.jetbrains.annotations.NotNull; @@ -51,10 +48,10 @@ public class BuildoutFacetType extends FacetType Date: Mon, 18 Oct 2010 21:08:04 +0400 Subject: [PATCH 27/40] fixed stupid error (PY-2101) --- python/helpers/pydev/pydevd_vars.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/helpers/pydev/pydevd_vars.py b/python/helpers/pydev/pydevd_vars.py index 52317b188934..164cf1613a8b 100644 --- a/python/helpers/pydev/pydevd_vars.py +++ b/python/helpers/pydev/pydevd_vars.py @@ -327,7 +327,7 @@ def resolveCompoundVariable(thread_id, frame_id, scope, attrs): var = frame.f_locals type, _typeName, resolver = getType(var) try: - resolver.resolve(var, attrs[0]) + resolver.resolve(var, attrList[0]) except: var = frame.f_globals From 094e7739dabdcc01cabfb8c1839deb319f433e33 Mon Sep 17 00:00:00 2001 From: Dmitry Jemerov Date: Wed, 20 Oct 2010 16:20:21 +0400 Subject: [PATCH 28/40] advance since-build --- python/pluginSrc/META-INF/plugin.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/pluginSrc/META-INF/plugin.xml b/python/pluginSrc/META-INF/plugin.xml index e4172461b0ed..b88d07d36e14 100644 --- a/python/pluginSrc/META-INF/plugin.xml +++ b/python/pluginSrc/META-INF/plugin.xml @@ -4,7 +4,7 @@ Pythonid Python - + Smart editing for Python scripts 2.6.3 com.intellij.modules.ultimate From 35d724468f28337d54e0583238563b7e61ee1a92 Mon Sep 17 00:00:00 2001 From: Dmitry Jemerov Date: Wed, 20 Oct 2010 17:13:44 +0400 Subject: [PATCH 29/40] copy runnerw from sources rather than binaries --- python/build/build-plugin.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/build/build-plugin.xml b/python/build/build-plugin.xml index 479a952d5402..d9d0c053eea4 100644 --- a/python/build/build-plugin.xml +++ b/python/build/build-plugin.xml @@ -121,7 +121,7 @@ - + From 99338882b16a3112e104192a2aa5c58223f21700 Mon Sep 17 00:00:00 2001 From: Dmitry Jemerov Date: Wed, 20 Oct 2010 18:07:03 +0400 Subject: [PATCH 30/40] copy runnerw to correct place --- python/build/build-plugin.xml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/python/build/build-plugin.xml b/python/build/build-plugin.xml index d9d0c053eea4..b4c6d4d2988b 100644 --- a/python/build/build-plugin.xml +++ b/python/build/build-plugin.xml @@ -121,9 +121,6 @@ - - - @@ -162,6 +159,8 @@ + + From f971df97b26daf3ab019b566c21309c18f08e664 Mon Sep 17 00:00:00 2001 From: Dmitry Trofimov Date: Wed, 20 Oct 2010 17:51:43 +0400 Subject: [PATCH 31/40] django run: invocation of custom manage.py, usage of settings.py path from settings --- python/helpers/pycharm/django_manage.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/python/helpers/pycharm/django_manage.py b/python/helpers/pycharm/django_manage.py index 951ff61099a3..1602c37b1055 100644 --- a/python/helpers/pycharm/django_manage.py +++ b/python/helpers/pycharm/django_manage.py @@ -1,8 +1,13 @@ #!/usr/bin/env python from pycharm.fix_getpass import fixGetpass -from django.core.management import execute_manager from pycharm import django_settings +import os +from runpy import run_module + +manage_file = os.getenv('PYCHARM_DJANGO_MANAGE_MODULE') +if not manage_file: + manage_file = 'manage' if __name__ == "__main__": fixGetpass() - execute_manager(django_settings) + run_module(manage_file) From f310d8c45dee2a5956129848f44ce2686b7a8af5 Mon Sep 17 00:00:00 2001 From: "Maxim.Mossienko" Date: Thu, 21 Oct 2010 16:25:12 +0400 Subject: [PATCH 32/40] IDEA-60125 False positive: static field is unused IDEA-58929 flex: fields, variables, functions occasionally marked as unused (while they're actually used) --- .../python/inspections/PyUnresolvedReferencesInspection.java | 2 +- .../jetbrains/python/inspections/PyUnusedLocalInspection.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/python/src/com/jetbrains/python/inspections/PyUnresolvedReferencesInspection.java b/python/src/com/jetbrains/python/inspections/PyUnresolvedReferencesInspection.java index 4899a2cf2ed4..253f061035bc 100644 --- a/python/src/com/jetbrains/python/inspections/PyUnresolvedReferencesInspection.java +++ b/python/src/com/jetbrains/python/inspections/PyUnresolvedReferencesInspection.java @@ -67,7 +67,7 @@ public class PyUnresolvedReferencesInspection extends PyInspection { } @Override - public void inspectionFinished(LocalInspectionToolSession session) { + public void inspectionFinished(LocalInspectionToolSession session, ProblemsHolder problemsHolder) { final Visitor visitor = session.getUserData(KEY); assert visitor != null; if (PyCodeInsightSettings.getInstance().HIGHLIGHT_UNUSED_IMPORTS) { diff --git a/python/src/com/jetbrains/python/inspections/PyUnusedLocalInspection.java b/python/src/com/jetbrains/python/inspections/PyUnusedLocalInspection.java index c2a26f187ade..4fdd00612ed4 100644 --- a/python/src/com/jetbrains/python/inspections/PyUnusedLocalInspection.java +++ b/python/src/com/jetbrains/python/inspections/PyUnusedLocalInspection.java @@ -40,7 +40,7 @@ public class PyUnusedLocalInspection extends PyInspection { } @Override - public void inspectionFinished(LocalInspectionToolSession session) { + public void inspectionFinished(LocalInspectionToolSession session, ProblemsHolder problemsHolder) { final PyUnusedLocalInspectionVisitor visitor = session.getUserData(KEY); if (visitor != null) { visitor.registerProblems(); From 70ae3ba700843f2dbd724485471fa00fb97ccb53 Mon Sep 17 00:00:00 2001 From: Dmitry Trofimov Date: Thu, 21 Oct 2010 15:53:10 +0400 Subject: [PATCH 33/40] added is django importable check for sdk selected in run configuration (PY-2153) --- .../jetbrains/python/psi/resolve/ResolveImportUtil.java | 9 +++++++++ .../python/run/AbstractPythonRunConfiguration.java | 3 ++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/python/src/com/jetbrains/python/psi/resolve/ResolveImportUtil.java b/python/src/com/jetbrains/python/psi/resolve/ResolveImportUtil.java index 1bcca02b1e97..239903e1d225 100644 --- a/python/src/com/jetbrains/python/psi/resolve/ResolveImportUtil.java +++ b/python/src/com/jetbrains/python/psi/resolve/ResolveImportUtil.java @@ -312,6 +312,15 @@ public class ResolveImportUtil { return visitor.results; } + @NotNull + public static List resolveModulesInRootProvider(@NotNull RootProvider rootProvider, @NotNull PsiManager psiManager, @NotNull PyQualifiedName moduleQualifiedName) { + ResolveInRootVisitor visitor = new ResolveInRootVisitor(moduleQualifiedName, psiManager, null); + for (VirtualFile file: rootProvider.getFiles(OrderRootType.CLASSES)) { + visitor.visitRoot(file); + } + return visitor.results; + } + // TODO: rewrite using resolveImportReference /** diff --git a/python/src/com/jetbrains/python/run/AbstractPythonRunConfiguration.java b/python/src/com/jetbrains/python/run/AbstractPythonRunConfiguration.java index dab282046cf6..a97ac81eb821 100644 --- a/python/src/com/jetbrains/python/run/AbstractPythonRunConfiguration.java +++ b/python/src/com/jetbrains/python/run/AbstractPythonRunConfiguration.java @@ -1,5 +1,6 @@ package com.jetbrains.python.run; +import com.google.common.collect.Maps; import com.intellij.execution.configuration.EnvironmentVariablesComponent; import com.intellij.execution.configurations.*; import com.intellij.openapi.module.Module; @@ -33,7 +34,7 @@ public abstract class AbstractPythonRunConfiguration extends ModuleBasedConfigur private String myWorkingDirectory = ""; private String mySdkHome = ""; private boolean myPassParentEnvs = true; - private Map myEnvs = new HashMap(); + private Map myEnvs = Maps.newHashMap(); private boolean myUseModuleSdk; public AbstractPythonRunConfiguration(final String name, final RunConfigurationModule module, final ConfigurationFactory factory) { From f26495ddb7c1ca3a4b6f325ee201e2fd5e28dd39 Mon Sep 17 00:00:00 2001 From: Dmitry Trofimov Date: Thu, 21 Oct 2010 16:08:00 +0400 Subject: [PATCH 34/40] django run configuration django check fixed for bundled django --- .../python/psi/resolve/ResolveImportUtil.java | 54 ++++++++++++------- 1 file changed, 35 insertions(+), 19 deletions(-) diff --git a/python/src/com/jetbrains/python/psi/resolve/ResolveImportUtil.java b/python/src/com/jetbrains/python/psi/resolve/ResolveImportUtil.java index 239903e1d225..40d575a7b5d0 100644 --- a/python/src/com/jetbrains/python/psi/resolve/ResolveImportUtil.java +++ b/python/src/com/jetbrains/python/psi/resolve/ResolveImportUtil.java @@ -1,5 +1,6 @@ package com.jetbrains.python.psi.resolve; +import com.google.common.collect.Sets; import com.intellij.openapi.extensions.Extensions; import com.intellij.openapi.module.Module; import com.intellij.openapi.module.ModuleUtil; @@ -23,9 +24,7 @@ import org.jetbrains.annotations.Nullable; import java.util.*; -import static com.jetbrains.python.psi.resolve.ResolveImportUtil.PointInImport.ROLE.AS_MODULE; -import static com.jetbrains.python.psi.resolve.ResolveImportUtil.PointInImport.ROLE.AS_NAME; -import static com.jetbrains.python.psi.resolve.ResolveImportUtil.PointInImport.ROLE.NONE; +import static com.jetbrains.python.psi.resolve.ResolveImportUtil.PointInImport.ROLE.*; /** * @author dcheryasov @@ -96,7 +95,7 @@ public class ResolveImportUtil { for (PsiElement element : psiElements) { final PsiElement init = PyUtil.turnDirIntoInit(element); if (init instanceof PsiFile) { - VirtualFile vFile = ((PsiFile) init).getVirtualFile(); + VirtualFile vFile = ((PsiFile)init).getVirtualFile(); if (vFile != null && vFile.getLength() > 0) { return element; } @@ -313,10 +312,14 @@ public class ResolveImportUtil { } @NotNull - public static List resolveModulesInRootProvider(@NotNull RootProvider rootProvider, @NotNull PsiManager psiManager, @NotNull PyQualifiedName moduleQualifiedName) { - ResolveInRootVisitor visitor = new ResolveInRootVisitor(moduleQualifiedName, psiManager, null); - for (VirtualFile file: rootProvider.getFiles(OrderRootType.CLASSES)) { - visitor.visitRoot(file); + public static List resolveModulesInRootProvider(@NotNull RootProvider rootProvider, + @NotNull Module module, + @NotNull PyQualifiedName moduleQualifiedName) { + ResolveInRootVisitor visitor = new ResolveInRootVisitor(moduleQualifiedName, PsiManager.getInstance(module.getProject()), null); + if (!visitModuleContentEntries(module, visitor)) { + for (VirtualFile file : rootProvider.getFiles(OrderRootType.CLASSES)) { + visitor.visitRoot(file); + } } return visitor.results; } @@ -397,7 +400,6 @@ public class ResolveImportUtil { } else { visitSdkRoots(elt, visitor); - } } @@ -417,26 +419,36 @@ public class ResolveImportUtil { private static void visitRoots(Module module, RootVisitor visitor) { // TODO: implement a proper module-like approach in PyCharm for "project's dirs on pythonpath", minding proper search order // Module-based approach works only in the IDEA plugin. + if (visitModuleContentEntries(module, visitor)) return; + // else look in SDK roots + visitModuleSdkRoots(visitor, module); + } + + private static boolean visitModuleContentEntries(Module module, RootVisitor visitor) { ModuleRootManager rootManager = ModuleRootManager.getInstance(module); // look in module sources boolean sourceEntriesMissing = true; - Set contentRoots = new java.util.HashSet(); + Set contentRoots = Sets.newHashSet(); for (ContentEntry entry : rootManager.getContentEntries()) { VirtualFile rootFile = entry.getFile(); - if (rootFile != null && !visitor.visitRoot(rootFile)) return; + if (rootFile != null && !visitor.visitRoot(rootFile)) return true; contentRoots.add(rootFile); for (VirtualFile folder : entry.getSourceFolderFiles()) { sourceEntriesMissing = false; - if (!visitor.visitRoot(folder)) return; + if (!visitor.visitRoot(folder)) return true; } } if (sourceEntriesMissing) { // fallback for a case without any source entries: use project root VirtualFile projectRoot = module.getProject().getBaseDir(); - if (projectRoot != null && !contentRoots.contains(projectRoot) && !visitor.visitRoot(projectRoot)) return; + if (projectRoot != null && !contentRoots.contains(projectRoot) && !visitor.visitRoot(projectRoot)) return true; } - // else look in SDK roots + return false; + } + + private static void visitModuleSdkRoots(@NotNull RootVisitor visitor, @NotNull Module module) { + ModuleRootManager rootManager = ModuleRootManager.getInstance(module); rootManager.orderEntries().process(new SdkRootVisitingPolicy(visitor), null); } @@ -524,7 +536,10 @@ public class ResolveImportUtil { } @Nullable - private static PsiElement resolveInRoot(VirtualFile root, PyQualifiedName qualifiedName, PsiManager psiManager, @Nullable PsiFile foothold_file) { + private static PsiElement resolveInRoot(VirtualFile root, + PyQualifiedName qualifiedName, + PsiManager psiManager, + @Nullable PsiFile foothold_file) { PsiElement module = root.isDirectory() ? psiManager.findDirectory(root) : psiManager.findFile(root); for (String component : qualifiedName.getComponents()) { if (component == null) { @@ -657,7 +672,8 @@ public class ResolveImportUtil { } VirtualFile skeletonsRoot = findSkeletonsRoot(dir); if (skeletonsRoot != null && relativeName != null) { - VirtualFile skeletonsVFile = relativeName.length() == 0 ? skeletonsRoot : skeletonsRoot.findFileByRelativePath(relativeName.replace(".", "/")); + VirtualFile skeletonsVFile = + relativeName.length() == 0 ? skeletonsRoot : skeletonsRoot.findFileByRelativePath(relativeName.replace(".", "/")); if (skeletonsVFile != null) { return dir.getManager().findDirectory(skeletonsVFile); } @@ -697,7 +713,7 @@ public class ResolveImportUtil { List result = StringUtil.split(relativePath, "/"); if (myResult == null || result.size() < myResult.size()) { if (result.size() > 0) { - result.set(result.size()-1, FileUtil.getNameWithoutExtension(result.get(result.size()-1))); + result.set(result.size() - 1, FileUtil.getNameWithoutExtension(result.get(result.size() - 1))); } myResult = result; } @@ -772,8 +788,9 @@ public class ResolveImportUtil { /** * When a name is imported from a module, tries to find the definition of that name inside the module, * as opposed to looking for submodules. + * * @param where an element related to the name, presumably inside import - * @param name the name to find + * @param name the name to find * @return found element, or null. */ @Nullable @@ -837,7 +854,6 @@ public class ResolveImportUtil { */ AS_NAME } - } /** From e222a72b1f539679939b0640d840b26f19d923ba Mon Sep 17 00:00:00 2001 From: "Maxim.Mossienko" Date: Thu, 21 Oct 2010 16:50:40 +0400 Subject: [PATCH 35/40] do not break Python plugin for a while --- .../python/inspections/PyUnresolvedReferencesInspection.java | 2 +- .../jetbrains/python/inspections/PyUnusedLocalInspection.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/python/src/com/jetbrains/python/inspections/PyUnresolvedReferencesInspection.java b/python/src/com/jetbrains/python/inspections/PyUnresolvedReferencesInspection.java index 253f061035bc..4899a2cf2ed4 100644 --- a/python/src/com/jetbrains/python/inspections/PyUnresolvedReferencesInspection.java +++ b/python/src/com/jetbrains/python/inspections/PyUnresolvedReferencesInspection.java @@ -67,7 +67,7 @@ public class PyUnresolvedReferencesInspection extends PyInspection { } @Override - public void inspectionFinished(LocalInspectionToolSession session, ProblemsHolder problemsHolder) { + public void inspectionFinished(LocalInspectionToolSession session) { final Visitor visitor = session.getUserData(KEY); assert visitor != null; if (PyCodeInsightSettings.getInstance().HIGHLIGHT_UNUSED_IMPORTS) { diff --git a/python/src/com/jetbrains/python/inspections/PyUnusedLocalInspection.java b/python/src/com/jetbrains/python/inspections/PyUnusedLocalInspection.java index 4fdd00612ed4..c2a26f187ade 100644 --- a/python/src/com/jetbrains/python/inspections/PyUnusedLocalInspection.java +++ b/python/src/com/jetbrains/python/inspections/PyUnusedLocalInspection.java @@ -40,7 +40,7 @@ public class PyUnusedLocalInspection extends PyInspection { } @Override - public void inspectionFinished(LocalInspectionToolSession session, ProblemsHolder problemsHolder) { + public void inspectionFinished(LocalInspectionToolSession session) { final PyUnusedLocalInspectionVisitor visitor = session.getUserData(KEY); if (visitor != null) { visitor.registerProblems(); From 2a984a8b66ed13471339c3f2559252f2a7b9679a Mon Sep 17 00:00:00 2001 From: Dmitry Trofimov Date: Thu, 21 Oct 2010 18:06:05 +0400 Subject: [PATCH 36/40] jdk->sdk rename refactoring --- .../com/jetbrains/python/module/PythonSdkChooserPanel.java | 2 +- python/src/com/jetbrains/python/psi/impl/PyBuiltinCache.java | 2 +- .../src/com/jetbrains/python/psi/stubs/PyClassNameIndex.java | 2 +- .../jetbrains/python/run/AbstractPythonRunConfiguration.java | 2 +- python/src/com/jetbrains/python/sdk/PythonSdkType.java | 4 ++-- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/python/pluginSrc/com/jetbrains/python/module/PythonSdkChooserPanel.java b/python/pluginSrc/com/jetbrains/python/module/PythonSdkChooserPanel.java index 579492811e38..c97115b6a8b1 100644 --- a/python/pluginSrc/com/jetbrains/python/module/PythonSdkChooserPanel.java +++ b/python/pluginSrc/com/jetbrains/python/module/PythonSdkChooserPanel.java @@ -57,7 +57,7 @@ public class PythonSdkChooserPanel extends JComponent { myJdkChooser.setAllowedJdkTypes(new SdkType[]{PythonSdkType.getInstance()}); - final Sdk selectedJdk = project == null ? null : ProjectRootManager.getInstance(project).getProjectJdk(); + final Sdk selectedJdk = project == null ? null : ProjectRootManager.getInstance(project).getProjectSdk(); myJdkChooser.updateList(selectedJdk, null); } diff --git a/python/src/com/jetbrains/python/psi/impl/PyBuiltinCache.java b/python/src/com/jetbrains/python/psi/impl/PyBuiltinCache.java index a0116c89bd81..143fa5879dcf 100644 --- a/python/src/com/jetbrains/python/psi/impl/PyBuiltinCache.java +++ b/python/src/com/jetbrains/python/psi/impl/PyBuiltinCache.java @@ -85,7 +85,7 @@ public class PyBuiltinCache { final VirtualFile vfile = psifile.getVirtualFile(); if (vfile != null) { // reality final ProjectRootManager projectRootManager = ProjectRootManager.getInstance(project); - sdk = projectRootManager.getProjectJdk(); + sdk = projectRootManager.getProjectSdk(); if (sdk == null) { final List orderEntries = projectRootManager.getFileIndex().getOrderEntriesForFile(vfile); for (OrderEntry orderEntry : orderEntries) { diff --git a/python/src/com/jetbrains/python/psi/stubs/PyClassNameIndex.java b/python/src/com/jetbrains/python/psi/stubs/PyClassNameIndex.java index c35af3f7768b..3e0609a6db02 100644 --- a/python/src/com/jetbrains/python/psi/stubs/PyClassNameIndex.java +++ b/python/src/com/jetbrains/python/psi/stubs/PyClassNameIndex.java @@ -49,7 +49,7 @@ public class PyClassNameIndex extends StringStubIndexExtension { * @return the resulting scope */ public static GlobalSearchScope projectWithLibrariesScope(Project project) { - final Sdk sdk = ProjectRootManager.getInstance(project).getProjectJdk(); + final Sdk sdk = ProjectRootManager.getInstance(project).getProjectSdk(); // TODO cache the scope in project userdata (update when SDK paths change or different project SDK is selected) if (sdk != null && sdk.getSdkType() instanceof PythonSdkType) { VirtualFile libDir = findLibDir(sdk.getRootProvider().getFiles(OrderRootType.CLASSES)); diff --git a/python/src/com/jetbrains/python/run/AbstractPythonRunConfiguration.java b/python/src/com/jetbrains/python/run/AbstractPythonRunConfiguration.java index a97ac81eb821..508a449ba5eb 100644 --- a/python/src/com/jetbrains/python/run/AbstractPythonRunConfiguration.java +++ b/python/src/com/jetbrains/python/run/AbstractPythonRunConfiguration.java @@ -66,7 +66,7 @@ public abstract class AbstractPythonRunConfiguration extends ModuleBasedConfigur else { if (!myUseModuleSdk) { if (StringUtil.isEmptyOrSpaces(getSdkHome())) { - final Sdk projectSdk = ProjectRootManager.getInstance(getProject()).getProjectJdk(); + final Sdk projectSdk = ProjectRootManager.getInstance(getProject()).getProjectSdk(); if (projectSdk == null || !(projectSdk.getSdkType() instanceof PythonSdkType)) { throw new RuntimeConfigurationError(PyBundle.message("runcfg.unittest.no_sdk")); } diff --git a/python/src/com/jetbrains/python/sdk/PythonSdkType.java b/python/src/com/jetbrains/python/sdk/PythonSdkType.java index 99e713e801f0..a83a06f2b717 100644 --- a/python/src/com/jetbrains/python/sdk/PythonSdkType.java +++ b/python/src/com/jetbrains/python/sdk/PythonSdkType.java @@ -402,7 +402,7 @@ public class PythonSdkType extends SdkType { final ProgressManager progman = ProgressManager.getInstance(); final Ref success = new Ref(); success.set(true); - final Task.Modal setup_task = new Task.Modal(project, "Setting up library files for " + sdk.getName(), false) { + final Task.Modal setupTask = new Task.Modal(project, "Setting up library files for " + sdk.getName(), false) { public void run(@NotNull final ProgressIndicator indicator) { try { @@ -418,7 +418,7 @@ public class PythonSdkType extends SdkType { } } }; - progman.run(setup_task); + progman.run(setupTask); return success.get(); } From 94b54433da99b97506ba4c63b17ae11740fbcedf Mon Sep 17 00:00:00 2001 From: Dmitry Trofimov Date: Fri, 22 Oct 2010 19:46:31 +0400 Subject: [PATCH 37/40] 1)adding of python interpreter paths without removing on reload 2)python interpreter paths added to PYTHONPATH variable on python run PY-2136 --- .../python/run/PythonCommandLineState.java | 31 ++++- .../python/sdk/PythonSdkAdditionalData.java | 107 ++++++++++++++++++ .../jetbrains/python/sdk/PythonSdkFlavor.java | 9 ++ .../jetbrains/python/sdk/PythonSdkType.java | 5 +- 4 files changed, 145 insertions(+), 7 deletions(-) create mode 100644 python/src/com/jetbrains/python/sdk/PythonSdkAdditionalData.java diff --git a/python/src/com/jetbrains/python/run/PythonCommandLineState.java b/python/src/com/jetbrains/python/run/PythonCommandLineState.java index 7613d58095fa..3f49b8b38152 100644 --- a/python/src/com/jetbrains/python/run/PythonCommandLineState.java +++ b/python/src/com/jetbrains/python/run/PythonCommandLineState.java @@ -1,5 +1,6 @@ package com.jetbrains.python.run; +import com.google.common.collect.Lists; import com.intellij.execution.DefaultExecutionResult; import com.intellij.execution.ExecutionException; import com.intellij.execution.ExecutionResult; @@ -17,9 +18,14 @@ import com.intellij.execution.runners.ExecutionEnvironment; import com.intellij.execution.runners.ProgramRunner; import com.intellij.execution.ui.ConsoleView; import com.intellij.openapi.project.Project; +import com.intellij.openapi.projectRoots.Sdk; +import com.intellij.openapi.roots.OrderRootType; +import com.intellij.openapi.util.io.FileUtil; +import com.intellij.openapi.vfs.VirtualFile; import com.intellij.util.containers.HashMap; import com.jetbrains.python.sdk.PythonEnvUtil; import com.jetbrains.python.sdk.PythonSdkFlavor; +import com.jetbrains.python.sdk.PythonSdkType; import org.jetbrains.annotations.NotNull; import java.util.List; @@ -61,12 +67,13 @@ public abstract class PythonCommandLineState extends CommandLineState { } @NotNull - protected ConsoleView createAndAttachConsole(Project project, ProcessHandler processHandler, Executor executor) throws ExecutionException { + protected ConsoleView createAndAttachConsole(Project project, ProcessHandler processHandler, Executor executor) + throws ExecutionException { final TextConsoleBuilder consoleBuilder = TextConsoleBuilderFactory.getInstance().createBuilder(project); for (Filter filter : myFilters) { consoleBuilder.addFilter(filter); } - + final ConsoleView consoleView = consoleBuilder.getConsole(); consoleView.attachToProcess(processHandler); return consoleView; @@ -78,6 +85,7 @@ public abstract class PythonCommandLineState extends CommandLineState { /** * Patches the command line parameters applying patchers from first to last, and then runs it. + * * @param patchers any number of patchers; any patcher may be null, and the whole argument may be null. * @return handler of the started process * @throws ExecutionException @@ -93,7 +101,7 @@ public abstract class PythonCommandLineState extends CommandLineState { public GeneralCommandLine generateCommandLine(CommandLinePatcher[] patchers) throws ExecutionException { GeneralCommandLine commandLine = generateCommandLine(); if (patchers != null) { - for (CommandLinePatcher patcher: patchers) { + for (CommandLinePatcher patcher : patchers) { if (patcher != null) patcher.patchCommandLine(commandLine); } } @@ -121,7 +129,8 @@ public abstract class PythonCommandLineState extends CommandLineState { /** * Creates a number of parameter groups in the command line: * GROUP_EXE_OPTIONS, GROUP_DEBUGGER, GROUP_SCRIPT. - * These are necessary for command line patchers to work properly. + * These are necessary for command line patchers to work properly. + * * @param commandLine */ public static void createStandardGroupsIn(GeneralCommandLine commandLine) { @@ -133,10 +142,12 @@ public abstract class PythonCommandLineState extends CommandLineState { protected void initEnvironment(GeneralCommandLine commandLine) { Map envs = myConfig.getEnvs(); - if (envs == null) + if (envs == null) { envs = new HashMap(); - else + } + else { envs = new HashMap(envs); + } addPredefinedEnvironmentVariables(envs, myConfig.isPassParentEnvs()); addCommonEnvironmentVariables(envs); @@ -154,6 +165,14 @@ public abstract class PythonCommandLineState extends CommandLineState { if (flavor != null) { flavor.addPredefinedEnvironmentVariables(envs); } + + Sdk pythonSdk = PythonSdkType.findSdkByPath(myConfig.getSdkHome()); + VirtualFile[] paths = pythonSdk.getRootProvider().getFiles(OrderRootType.CLASSES); + List pathList = Lists.newArrayList(); + for (VirtualFile file : paths) { + pathList.add(FileUtil.toSystemDependentName(file.getPath())); + } + PythonSdkFlavor.initPythonPath(envs, passParentEnvs, pathList); } protected void setRunnerPath(GeneralCommandLine commandLine) throws ExecutionException { diff --git a/python/src/com/jetbrains/python/sdk/PythonSdkAdditionalData.java b/python/src/com/jetbrains/python/sdk/PythonSdkAdditionalData.java new file mode 100644 index 000000000000..68f436cf35c8 --- /dev/null +++ b/python/src/com/jetbrains/python/sdk/PythonSdkAdditionalData.java @@ -0,0 +1,107 @@ +package com.jetbrains.python.sdk; + +import com.google.common.collect.Sets; +import com.intellij.openapi.options.ConfigurationException; +import com.intellij.openapi.projectRoots.SdkAdditionalData; +import com.intellij.openapi.projectRoots.SdkModel; +import com.intellij.openapi.vfs.VirtualFile; +import com.jetbrains.django.util.VirtualFileUtil; +import org.jdom.Element; +import org.jetbrains.annotations.NonNls; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.LinkedList; +import java.util.List; +import java.util.Set; + +/** +* @author traff +*/ +public class PythonSdkAdditionalData implements SdkAdditionalData { + @NonNls private static final String PATHS_ADDED_BY_USER_ROOT = "PATHS_ADDED_BY_USER_ROOT"; + @NonNls private static final String PATH_ADDED_BY_USER = "PATH_ADDED_BY_USER"; + @NonNls private static final String PATHS_REMOVED_BY_USER_ROOT = "PATHS_REMOVED_BY_USER_ROOT"; + @NonNls private static final String PATH_REMOVED_BY_USER = "PATH_REMOVED_BY_USER"; + + + private Set myAddedPaths = Sets.newHashSet(); + private Set myExcludedPaths = Sets.newHashSet(); + + public Object clone() throws CloneNotSupportedException { + try { + final PythonSdkAdditionalData copy = (PythonSdkAdditionalData)super.clone(); + copy.setAddedPaths(getAddedPaths()); + copy.setExcludedPaths(getExcludedPaths()); + return copy; + } + catch (CloneNotSupportedException e) { + return null; + } + } + + public Set getAddedPaths() { + return myAddedPaths; + } + + public void setAddedPaths(Set addedPaths) { + myAddedPaths = Sets.newHashSet(addedPaths); + } + + public Set getExcludedPaths() { + return myExcludedPaths; + } + + public void setExcludedPaths(Set excludedPaths) { + myExcludedPaths = Sets.newHashSet(excludedPaths); + } + + @Override + public void checkValid(SdkModel sdkModel) throws ConfigurationException { + + } + + public void save(@NotNull final Element rootElement) { + for (VirtualFile addedPath : myAddedPaths) { + final Element child = new Element(PATHS_ADDED_BY_USER_ROOT); + child.setAttribute(PATH_ADDED_BY_USER, addedPath.getPath()); + rootElement.addContent(child); + } + + for (VirtualFile removed : myExcludedPaths) { + final Element child = new Element(PATHS_REMOVED_BY_USER_ROOT); + child.setAttribute(PATH_REMOVED_BY_USER, removed.getPath()); + rootElement.addContent(child); + } + } + + @NotNull + public static PythonSdkAdditionalData load(@Nullable Element element) { + final PythonSdkAdditionalData data = new PythonSdkAdditionalData(); + + data.setAddedPaths(loadStringList(element, PATHS_ADDED_BY_USER_ROOT, PATH_ADDED_BY_USER)); + data.setExcludedPaths(loadStringList(element, PATHS_REMOVED_BY_USER_ROOT, PATH_REMOVED_BY_USER)); + + return data; + } + + private static Set loadStringList(Element element, String rootName, String attrName) { + final List paths = new LinkedList(); + if (element != null) { + final List list = element.getChildren(rootName); + if (list != null) { + for (Object o : list) { + paths.add(((Element)o).getAttribute(attrName).getValue()); + } + } + } + final Set files = Sets.newHashSet(); + for (String path : paths) { + VirtualFile vf = VirtualFileUtil.findFile(path); + if (vf != null) { + files.add(vf); + } + } + return files; + } +} diff --git a/python/src/com/jetbrains/python/sdk/PythonSdkFlavor.java b/python/src/com/jetbrains/python/sdk/PythonSdkFlavor.java index 8092324946a2..88ae00d3fe78 100644 --- a/python/src/com/jetbrains/python/sdk/PythonSdkFlavor.java +++ b/python/src/com/jetbrains/python/sdk/PythonSdkFlavor.java @@ -4,6 +4,7 @@ import com.intellij.execution.configurations.GeneralCommandLine; import com.intellij.execution.process.ProcessOutput; import com.intellij.openapi.util.SystemInfo; import com.intellij.openapi.util.io.FileUtil; +import com.intellij.openapi.util.text.StringUtil; import org.jetbrains.annotations.Nullable; import java.io.File; @@ -22,6 +23,14 @@ public abstract class PythonSdkFlavor { return pythonPath; } + public static void initPythonPath(Map envs, boolean passParentEnvs, List pythonPathList) { + String pythonPath = StringUtil.join(pythonPathList, File.pathSeparator); + if (passParentEnvs && !envs.containsKey(PYTHONPATH)) { + pythonPath = appendSystemPythonPath(pythonPath); + } + addToPythonPath(envs, pythonPath); + } + public Collection suggestHomePaths() { return Collections.emptyList(); } diff --git a/python/src/com/jetbrains/python/sdk/PythonSdkType.java b/python/src/com/jetbrains/python/sdk/PythonSdkType.java index a83a06f2b717..24e622798b1d 100644 --- a/python/src/com/jetbrains/python/sdk/PythonSdkType.java +++ b/python/src/com/jetbrains/python/sdk/PythonSdkType.java @@ -287,6 +287,9 @@ public class PythonSdkType extends SdkType { } public void saveAdditionalData(final SdkAdditionalData additionalData, final Element additional) { + if (additionalData instanceof PythonSdkAdditionalData ) { + ((PythonSdkAdditionalData)additionalData).save(additional); + } } @Override @@ -321,7 +324,7 @@ public class PythonSdkType extends SdkType { // Don't fix skeletons here, PythonSdkUpdater will take care of that (see PY-1226 - no progress will be displayed if skeletons // generation is invoked from here - return null; + return PythonSdkAdditionalData.load(additional); } private boolean switchPathToInterpreter(Sdk currentSdk, String... variants) { From bc3816dba7083de6fd7def4611e4573a39eb4ef2 Mon Sep 17 00:00:00 2001 From: Ekaterina Tuzova Date: Mon, 25 Oct 2010 14:37:01 +0400 Subject: [PATCH 38/40] Fixed PY-1433 ("All tests in folder" allows to specify pattern for files to be considered tests) Fixed PY-1964 (The setUpClass fixture from unittest2 is supported.) Fixed PY-2124 (Running all tests in folder works with Python 3) --- python/helpers/pycharm/utrunner.py | 48 ++++++++++++++++--- .../com/jetbrains/python/PyBundle.properties | 1 + .../PythonUnitTestCommandLineState.java | 6 ++- .../PythonUnitTestRunConfiguration.java | 13 +++++ .../PythonUnitTestRunConfigurationForm.form | 16 +++++-- .../PythonUnitTestRunConfigurationForm.java | 22 +++++++++ .../PythonUnitTestRunConfigurationParams.java | 4 ++ 7 files changed, 99 insertions(+), 11 deletions(-) diff --git a/python/helpers/pycharm/utrunner.py b/python/helpers/pycharm/utrunner.py index bf42c8291b90..82980c27c80a 100644 --- a/python/helpers/pycharm/utrunner.py +++ b/python/helpers/pycharm/utrunner.py @@ -3,9 +3,19 @@ import os import imp import sys import types +import re from pycharm.tcmessages import TeamcityServiceMessages from pycharm.tcunittest import TeamcityTestRunner +try: + import unittest2 as unittest +except: + # python version doesn't have unittest2 + pass + +PYTHON_VERSION_MAJOR = sys.version_info[0] +PYTHON_VERSION_MINOR = sys.version_info[1] + ENABLE_DEBUG_LOGGING = False if os.getenv("UTRUNNER_ENABLE_DEBUG_LOGGING"): ENABLE_DEBUG_LOGGING = True @@ -39,9 +49,28 @@ def walkModules(modules, dirname, names): def loadModulesFromFolderRec(folder): modules = [] - os.path.walk(folder, walkModules, modules) + if PYTHON_VERSION_MAJOR == 3: + for root, dirs, files in os.walk(folder, walkModules, modules): + for name in files: + if name.endswith(".py"): + modules.append(loadSource(os.path.join(root, name))) + else: + os.path.walk(folder, walkModules, modules) + return modules +def loadModulesFromFolderUsingPattern(folder, pattern): + ''' loads modules from folder , + check if module name matches given pattern''' + modules = loadModulesFromFolderRec(folder) + result = [] + prog = re.compile(pattern) + + for module in modules: + if prog.match(module.__name__): + result.append(module) + return result + testLoader = unittest.TestLoader() all = unittest.TestSuite() @@ -53,12 +82,19 @@ for arg in sys.argv[1:]: a = arg.split("::") if len(a) == 1: # From module or folder - if a[0].endswith("/"): - debug("/ from folder " + a[0]) - modules = loadModulesFromFolderRec(a[0]) + a_splitted = a[0].split(";") + if len(a_splitted) != 1: + # means we have pattern to match against + if a_splitted[0].endswith("/"): + debug("/ from folder " + a_splitted[0] + ". Use pattern: " + a_splitted[1]) + modules = loadModulesFromFolderUsingPattern(a_splitted[0], a_splitted[1]) else: - debug("/ from module " + a[0]) - modules = [loadSource(a[0])] + if a[0].endswith("/"): + debug("/ from folder " + a[0]) + modules = loadModulesFromFolderRec(a[0]) + else: + debug("/ from module " + a[0]) + modules = [loadSource(a[0])] for module in modules: all.addTests(testLoader.loadTestsFromModule(module)._tests) diff --git a/python/src/com/jetbrains/python/PyBundle.properties b/python/src/com/jetbrains/python/PyBundle.properties index 7237e8fb1532..39925bf8963e 100644 --- a/python/src/com/jetbrains/python/PyBundle.properties +++ b/python/src/com/jetbrains/python/PyBundle.properties @@ -434,6 +434,7 @@ runcfg.captions.script_parameters_dialog=Enter script parameters runcfg.captions.interpreter_options_dialog=Enter interpreter options sdk.error.invalid.interpreter.name.$0=Invalid Python interpeter name '{0}'! sdk.select.path=Select Python Interpreter +runcfg.unittest.dlg.pattern=Pattern: # Consoles messages python.console=Python Console diff --git a/python/src/com/jetbrains/python/testing/PythonUnitTestCommandLineState.java b/python/src/com/jetbrains/python/testing/PythonUnitTestCommandLineState.java index b773baf87b52..4d1853505a4d 100644 --- a/python/src/com/jetbrains/python/testing/PythonUnitTestCommandLineState.java +++ b/python/src/com/jetbrains/python/testing/PythonUnitTestCommandLineState.java @@ -56,7 +56,11 @@ public class PythonUnitTestCommandLineState extends PythonTestCommandLineStateBa specs.add(myConfig.getScriptName() + "::" + myConfig.getClassName() + "::" + myConfig.getMethodName()); break; case TEST_FOLDER: - specs.add(myConfig.getFolderName() + "/"); + if (!myConfig.getPattern().isEmpty()) + specs.add(myConfig.getFolderName() + "/" + ";" + myConfig.getPattern() + "$"); + else + specs.add(myConfig.getFolderName() + "/"); + // TODO[kate]:think about delimiter between folderName and Pattern break; default: throw new IllegalArgumentException("Unknown test type: " + myConfig.getTestType()); diff --git a/python/src/com/jetbrains/python/testing/PythonUnitTestRunConfiguration.java b/python/src/com/jetbrains/python/testing/PythonUnitTestRunConfiguration.java index ed0e617ce783..50ce980ece99 100644 --- a/python/src/com/jetbrains/python/testing/PythonUnitTestRunConfiguration.java +++ b/python/src/com/jetbrains/python/testing/PythonUnitTestRunConfiguration.java @@ -25,6 +25,7 @@ public class PythonUnitTestRunConfiguration extends AbstractPythonRunConfigurati private String myScriptName = ""; private String myMethodName = ""; private String myFolderName = ""; + private String myPattern = ""; // pattern for modules in folder to match against private TestType myTestType = TestType.TEST_SCRIPT; protected PythonUnitTestRunConfiguration(RunConfigurationModule module, ConfigurationFactory configurationFactory, String name) { @@ -42,6 +43,7 @@ public class PythonUnitTestRunConfiguration extends AbstractPythonRunConfigurati myClassName = JDOMExternalizerUtil.readField(element, "CLASS_NAME"); myMethodName = JDOMExternalizerUtil.readField(element, "METHOD_NAME"); myFolderName = JDOMExternalizerUtil.readField(element, "FOLDER_NAME"); + myPattern = JDOMExternalizerUtil.readField(element, "PATTERN"); try { myTestType = TestType.valueOf(JDOMExternalizerUtil.readField(element, "TEST_TYPE")); @@ -54,10 +56,12 @@ public class PythonUnitTestRunConfiguration extends AbstractPythonRunConfigurati @Override public void writeExternal(Element element) throws WriteExternalException { super.writeExternal(element); + JDOMExternalizerUtil.writeField(element, "SCRIPT_NAME", myScriptName); JDOMExternalizerUtil.writeField(element, "CLASS_NAME", myClassName); JDOMExternalizerUtil.writeField(element, "METHOD_NAME", myMethodName); JDOMExternalizerUtil.writeField(element, "FOLDER_NAME", myFolderName); + JDOMExternalizerUtil.writeField(element, "PATTERN", myPattern); JDOMExternalizerUtil.writeField(element, "TEST_TYPE", myTestType.toString()); } @@ -77,6 +81,14 @@ public class PythonUnitTestRunConfiguration extends AbstractPythonRunConfigurati myClassName = className; } + public String getPattern() { + return myPattern; + } + + public void setPattern(String pattern) { + myPattern = pattern; + } + public String getFolderName() { return myFolderName; } @@ -188,5 +200,6 @@ public class PythonUnitTestRunConfiguration extends AbstractPythonRunConfigurati target.setFolderName(source.getFolderName()); target.setMethodName(source.getMethodName()); target.setTestType(source.getTestType()); + target.setPattern(source.getPattern()); } } diff --git a/python/src/com/jetbrains/python/testing/PythonUnitTestRunConfigurationForm.form b/python/src/com/jetbrains/python/testing/PythonUnitTestRunConfigurationForm.form index 3f7c024c076e..11d36d0baf88 100644 --- a/python/src/com/jetbrains/python/testing/PythonUnitTestRunConfigurationForm.form +++ b/python/src/com/jetbrains/python/testing/PythonUnitTestRunConfigurationForm.form @@ -8,7 +8,7 @@ - + @@ -18,7 +18,7 @@ - + @@ -26,7 +26,7 @@ - + @@ -42,12 +42,20 @@ - + + + + + + + + + diff --git a/python/src/com/jetbrains/python/testing/PythonUnitTestRunConfigurationForm.java b/python/src/com/jetbrains/python/testing/PythonUnitTestRunConfigurationForm.java index 7d4f4577d397..0f02254c4657 100644 --- a/python/src/com/jetbrains/python/testing/PythonUnitTestRunConfigurationForm.java +++ b/python/src/com/jetbrains/python/testing/PythonUnitTestRunConfigurationForm.java @@ -30,11 +30,13 @@ public class PythonUnitTestRunConfigurationForm implements PythonUnitTestRunConf private JRadioButton myTestClassRB; private JRadioButton myTestMethodRB; private JPanel myCommonOptionsPlaceholder; + private LabeledComponent myPatternComponent; private TextFieldWithBrowseButton myTestFolderTextField; private TextFieldWithBrowseButton myTestScriptTextField; private JTextField myTestMethodTextField; private JTextField myTestClassTextField; + private JTextField myPatternTextField; private final Project myProject; private final AbstractPyCommonOptionsForm myCommonOptionsForm; @@ -74,6 +76,14 @@ public class PythonUnitTestRunConfigurationForm implements PythonUnitTestRunConf myTestClassTextField.setText(className); } + public String getPattern() { + return myPatternTextField.getText().trim(); + } + + public void setPattern(String pattern) { + myPatternTextField.setText(pattern); + } + public String getFolderName() { return toSystemIndependentName(myTestFolderTextField.getText().trim()); } @@ -129,6 +139,7 @@ public class PythonUnitTestRunConfigurationForm implements PythonUnitTestRunConf myTestScriptComponent.setEnabled(testType != TestType.TEST_FOLDER); myTestClassComponent.setEnabled(testType == TestType.TEST_CLASS || testType == TestType.TEST_METHOD); myTestMethodComponent.setEnabled(testType == TestType.TEST_METHOD); + myPatternComponent.setEnabled(testType == TestType.TEST_FOLDER); } public JComponent getPanel() { @@ -182,6 +193,7 @@ public class PythonUnitTestRunConfigurationForm implements PythonUnitTestRunConf private void createUIComponents() { myTestClassComponent = createTestClassComponent(); myTestMethodComponent = createTestMethodComponent(); + myPatternComponent = createPatternComponent(); final Ref testsFolderTextFieldWrapper = new Ref(); myTestFolderComponent = createTestFolderComponent(testsFolderTextFieldWrapper); @@ -195,6 +207,16 @@ public class PythonUnitTestRunConfigurationForm implements PythonUnitTestRunConf title = PyBundle.message("runcfg.unittest.dlg.select.script.path"); PythonRunConfigurationFormUtil.addFileChooser(title, myTestScriptTextField, myProject); } + + private LabeledComponent createPatternComponent() { + myPatternTextField = new JTextField(); + + LabeledComponent myComponent = new LabeledComponent(); + myComponent.setComponent(myPatternTextField); + myComponent.setText(PyBundle.message("runcfg.unittest.dlg.pattern")); + + return myComponent; + } } diff --git a/python/src/com/jetbrains/python/testing/PythonUnitTestRunConfigurationParams.java b/python/src/com/jetbrains/python/testing/PythonUnitTestRunConfigurationParams.java index 5d38cc7758b3..adf3730fbc5f 100644 --- a/python/src/com/jetbrains/python/testing/PythonUnitTestRunConfigurationParams.java +++ b/python/src/com/jetbrains/python/testing/PythonUnitTestRunConfigurationParams.java @@ -22,4 +22,8 @@ public interface PythonUnitTestRunConfigurationParams { PythonUnitTestRunConfiguration.TestType getTestType(); void setTestType(PythonUnitTestRunConfiguration.TestType testType); + + String getPattern(); + void setPattern(String pattern); + } From 7f299594fa4dd2b32c94a19997003cb1a7d18286 Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Mon, 25 Oct 2010 14:56:20 +0400 Subject: [PATCH 39/40] Application.assertWriteAccess does really assert in tests, tests now run in EDT --- python/testSrc/com/jetbrains/python/PyIndentTest.java | 7 +------ python/testSrc/com/jetbrains/python/PyTypeTest.java | 7 +------ .../com/jetbrains/python/PythonCompletionTest.java | 9 ++------- .../python/fixtures/LightMarkedTestCase.java | 11 +++-------- .../jetbrains/python/fixtures/PyResolveTestCase.java | 7 +------ 5 files changed, 8 insertions(+), 33 deletions(-) diff --git a/python/testSrc/com/jetbrains/python/PyIndentTest.java b/python/testSrc/com/jetbrains/python/PyIndentTest.java index 5ae348eca1d0..aae064bc44c0 100644 --- a/python/testSrc/com/jetbrains/python/PyIndentTest.java +++ b/python/testSrc/com/jetbrains/python/PyIndentTest.java @@ -12,12 +12,7 @@ public class PyIndentTest extends PyLightFixtureTestCase { private void doTest(final String before, String after) { final String name = getTestName(false); - ApplicationManager.getApplication().runWriteAction(new Runnable() { - @Override - public void run() { - myFixture.configureByText(name + ".py", before); - } - }); + myFixture.configureByText(name + ".py", before); CommandProcessor.getInstance().executeCommand(myFixture.getProject(), new Runnable() { @Override public void run() { diff --git a/python/testSrc/com/jetbrains/python/PyTypeTest.java b/python/testSrc/com/jetbrains/python/PyTypeTest.java index 52b792086515..48a855dda208 100644 --- a/python/testSrc/com/jetbrains/python/PyTypeTest.java +++ b/python/testSrc/com/jetbrains/python/PyTypeTest.java @@ -107,12 +107,7 @@ public class PyTypeTest extends PyLightFixtureTestCase { } private PyType doTest(final String text) { - ApplicationManager.getApplication().runWriteAction(new Runnable() { - @Override - public void run() { - myFixture.configureByText(PythonFileType.INSTANCE, text); - } - }); + myFixture.configureByText(PythonFileType.INSTANCE, text); PyExpression expr = myFixture.findElementByText("expr", PyExpression.class); return expr.getType(TypeEvalContext.slow()); } diff --git a/python/testSrc/com/jetbrains/python/PythonCompletionTest.java b/python/testSrc/com/jetbrains/python/PythonCompletionTest.java index af7786863f13..e3244ccd3e5b 100644 --- a/python/testSrc/com/jetbrains/python/PythonCompletionTest.java +++ b/python/testSrc/com/jetbrains/python/PythonCompletionTest.java @@ -196,12 +196,7 @@ public class PythonCompletionTest extends PyLightFixtureTestCase { } public void testEmptyFile() { // PY-1845 - ApplicationManager.getApplication().runWriteAction(new Runnable() { - @Override - public void run() { - myFixture.configureByText(PythonFileType.INSTANCE, ""); - } - }); + myFixture.configureByText(PythonFileType.INSTANCE, ""); myFixture.completeBasic(); final List elements = myFixture.getLookupElementStrings(); assertTrue(elements.contains("import")); @@ -229,4 +224,4 @@ public class PythonCompletionTest extends PyLightFixtureTestCase { myFixture.completeBasic(); myFixture.checkResultByFile(dirname + "importedModule.after.py"); } -} \ No newline at end of file +} diff --git a/python/testSrc/com/jetbrains/python/fixtures/LightMarkedTestCase.java b/python/testSrc/com/jetbrains/python/fixtures/LightMarkedTestCase.java index 6871d2befc61..b5dcd11bac63 100644 --- a/python/testSrc/com/jetbrains/python/fixtures/LightMarkedTestCase.java +++ b/python/testSrc/com/jetbrains/python/fixtures/LightMarkedTestCase.java @@ -94,13 +94,8 @@ public abstract class LightMarkedTestCase extends PyLightFixtureTestCase { // create a file and map marks to PSI elements Map result = new HashMap(); - ApplicationManager.getApplication().runWriteAction(new Runnable() { - @Override - public void run() { - myFile = myFixture.addFileToProject(fileName, text.toString()); - myFixture.configureFromExistingVirtualFile(myFile.getVirtualFile()); - } - }); + myFile = myFixture.addFileToProject(fileName, text.toString()); + myFixture.configureFromExistingVirtualFile(myFile.getVirtualFile()); for (Map.Entry entry : offsets.entrySet()) { result.put(entry.getKey(), myFile.findElementAt(entry.getValue())); } @@ -111,4 +106,4 @@ public abstract class LightMarkedTestCase extends PyLightFixtureTestCase { String fname = getTestName(false) + ".py"; return configureByFile(fname); } -} \ No newline at end of file +} diff --git a/python/testSrc/com/jetbrains/python/fixtures/PyResolveTestCase.java b/python/testSrc/com/jetbrains/python/fixtures/PyResolveTestCase.java index ef93d9aee077..85d391024845 100644 --- a/python/testSrc/com/jetbrains/python/fixtures/PyResolveTestCase.java +++ b/python/testSrc/com/jetbrains/python/fixtures/PyResolveTestCase.java @@ -38,12 +38,7 @@ public abstract class PyResolveTestCase extends PyLightFixtureTestCase { assertTrue(offset >= 0); fileText = fileText.substring(0, offset) + fileText.substring(offset + MARKER.length()); final String finalFileText = fileText; - ApplicationManager.getApplication().runWriteAction(new Runnable() { - @Override - public void run() { - myFixture.configureByText(new File(filePath).getName(), finalFileText); - } - }); + myFixture.configureByText(new File(filePath).getName(), finalFileText); final PsiReference reference = myFixture.getFile().findReferenceAt(offset); return reference; } From 4e1735abdd8aaa562689a65bb72dd1b3fd56f2ce Mon Sep 17 00:00:00 2001 From: Oleg Shpynov Date: Tue, 26 Oct 2010 15:16:09 +0400 Subject: [PATCH 40/40] PY-2189 Do not perform autopopup handler in case of REPL console --- python/src/META-INF/python-plugin-common.xml | 2 ++ ...devCompletionAutopopupBlockingHandler.java | 24 +++++++++++++++++++ .../python/console/PydevLanguageConsole.java | 2 ++ 3 files changed, 28 insertions(+) create mode 100644 python/src/com/jetbrains/python/console/PydevCompletionAutopopupBlockingHandler.java diff --git a/python/src/META-INF/python-plugin-common.xml b/python/src/META-INF/python-plugin-common.xml index 5ad33c22ebac..b37d64a92fe9 100644 --- a/python/src/META-INF/python-plugin-common.xml +++ b/python/src/META-INF/python-plugin-common.xml @@ -150,6 +150,8 @@ + diff --git a/python/src/com/jetbrains/python/console/PydevCompletionAutopopupBlockingHandler.java b/python/src/com/jetbrains/python/console/PydevCompletionAutopopupBlockingHandler.java new file mode 100644 index 000000000000..d5393f33f5b3 --- /dev/null +++ b/python/src/com/jetbrains/python/console/PydevCompletionAutopopupBlockingHandler.java @@ -0,0 +1,24 @@ +package com.jetbrains.python.console; + +import com.intellij.codeInsight.editorActions.TypedHandlerDelegate; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Key; +import com.intellij.psi.PsiFile; + +/** + * @author oleg + * @date 10/26/10 + */ +public class PydevCompletionAutopopupBlockingHandler extends TypedHandlerDelegate { + + public static final Key REPL_KEY = new Key("python.repl.console.editor"); + + @Override + public Result checkAutoPopup(final char charTyped, final Project project, final Editor editor, final PsiFile file) { + if (editor.getUserData(REPL_KEY) != null){ + return Result.DEFAULT; + } + return Result.CONTINUE; + } +} diff --git a/python/src/com/jetbrains/python/console/PydevLanguageConsole.java b/python/src/com/jetbrains/python/console/PydevLanguageConsole.java index 53a218b82e25..c9e67b27f6f9 100644 --- a/python/src/com/jetbrains/python/console/PydevLanguageConsole.java +++ b/python/src/com/jetbrains/python/console/PydevLanguageConsole.java @@ -11,6 +11,8 @@ import com.jetbrains.python.console.pydev.PydevConsoleCommunication; public class PydevLanguageConsole extends LanguageConsoleImpl { public PydevLanguageConsole(final Project project, final String title) { super(project, title, PythonLanguage.getInstance(), false); + // Mark editor as console one, to prevent autopopup completion + getConsoleEditor().putUserData(PydevCompletionAutopopupBlockingHandler.REPL_KEY, new Object()); } public void setPydevConsoleCommunication(final PydevConsoleCommunication communication) {