Merge branch 'master' of git.labs.intellij.net:idea/ultimate

This commit is contained in:
Dmitry Trofimov
2010-12-14 22:12:31 +03:00
21 changed files with 131 additions and 100 deletions
Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

+1
View File
@@ -257,6 +257,7 @@ target('default': "Build artifacts") {
}
}
executeExternalAnt("file.name": "pycharm",
"dmg.image.name" : "${home}/python/build/DMG_background.png",
"$home/build/buildDmg.xml")
buildTarGz()
+28 -13
View File
@@ -7,6 +7,7 @@ import traceback
import datetime
from tcunittest import TeamcityTestResult
from tcmessages import TeamcityServiceMessages
class TeamcityDocTestResult(TeamcityTestResult):
"""
@@ -57,6 +58,20 @@ class DocTestRunner(doctest.DocTestRunner):
doctest.DocTestRunner.__init__(self, verbose, optionflags)
self.stream = sys.stdout
self.result = TeamcityDocTestResult(self.stream)
self._tests = []
def addTests(self, tests):
self._tests.extend(tests)
def addTest(self, test):
self._tests.append(test)
def countTests(self):
return len(self._tests)
def start(self):
for test in self._tests:
self.run(test)
def __run(self, test, compileflags, out):
failures = tries = 0
@@ -152,6 +167,8 @@ modules = {}
from utrunner import debug, getModuleName, PYTHON_VERSION_MAJOR
runner = DocTestRunner()
def loadSource(fileName):
"""
loads source from fileName,
@@ -175,15 +192,13 @@ def testfile(filename):
text, filename = doctest._load_testfile(filename, None, False)
name = os.path.basename(filename)
globs = {}
globs['__name__'] = '__main__'
globs = {'__name__': '__main__'}
runner = DocTestRunner()
parser = doctest.DocTestParser()
# Read the file, convert it to a test, and run it.
test = parser.get_doctest(text, globs, name, filename, 0)
if test.examples:
runner.run(test)
runner.addTest(test)
def walkModules(modules, dirname, names):
walkModulesUsingPattern(modules, dirname, names)
@@ -229,7 +244,6 @@ def testFilesInFolderUsingPattern(folder, pattern = ".*"):
return result
if __name__ == "__main__":
runner = DocTestRunner()
finder = doctest.DocTestFinder()
for arg in sys.argv[1:]:
@@ -265,7 +279,7 @@ if __name__ == "__main__":
tests = finder.find(module, module.__name__)
for test in tests:
if test.examples:
runner.run(test)
runner.addTest(test)
elif len(a) == 2:
# From testcase
@@ -277,8 +291,7 @@ if __name__ == "__main__":
if hasattr(module, a[1]):
testcase = getattr(module, a[1])
tests = finder.find(testcase, testcase.__name__)
for test in tests:
runner.run(test)
runner.addTests(tests)
else:
raise NameError('Module "%s" has no class "%s"' % (a[0], a[1]))
else:
@@ -293,8 +306,7 @@ if __name__ == "__main__":
if hasattr(module, a[2]):
testcase = getattr(module, a[2])
tests = finder.find(testcase, testcase.__name__)
for test in tests:
runner.run(test)
runner.addTests(tests)
else:
raise NameError('Module "%s" has no method "%s"' % (a[0], a[2]))
else:
@@ -304,9 +316,12 @@ if __name__ == "__main__":
if hasattr(testCaseClass, a[2]):
testcase = getattr(testCaseClass, a[2])
tests = finder.find(testcase, testcase.__name__)
for test in tests:
runner.run(test)
runner.addTests(tests)
else:
raise NameError('Class "%s" has no function "%s"' % (testCaseClass, a[2]))
else:
raise NameError('Module "%s" has no class "%s"' % (module, a[1]))
raise NameError('Module "%s" has no class "%s"' % (module, a[1]))
debug("/ Loaded " + str(runner.countTests()) + " tests")
TeamcityServiceMessages(sys.stdout).testCount(runner.countTests())
runner.start()
-7
View File
@@ -1,4 +1,3 @@
import unittest
import os
import imp
import sys
@@ -7,12 +6,6 @@ import re
from tcmessages import TeamcityServiceMessages
from tcunittest import TeamcityTestRunner
try:
import unittest2 as unittest
except:
# python version doesn't have unittest2
pass
from nose_helper import TestLoader, ContextSuite
PYTHON_VERSION_MAJOR = sys.version_info[0]
-63
View File
@@ -1,63 +0,0 @@
#!/usr/bin/env python
from unittest import TestResult
class TestListener:
""" Simulate a Java interface by providing an abstract class
All methods need to be implemented by classes extending TestListener
"""
# Test was successful.
def addSuccess(self, test):
raise NotImplementedError, "TestListener.addSuccess()"
# An error occured
def addError(self, test, err):
raise NotImplementedError, "TestListener.addError()"
# A failure occurred.
def addFailure(self, test, err):
raise NotImplementedError, "TestListener.addFailure()"
# A test started.
def startTest(self, test):
raise NotImplementedError, "TestListener.startTest()"
# A test ended.
def endTest(self, test):
raise NotImplementedError, "TestListener.endTest()"
class TestResultWithListeners(TestResult):
def __init__(self):
TestResult.__init__(self)
self.listeners = []
def startTest(self, test):
TestResult.startTest(self, test)
for listener in self.listeners:
listener.startTest(test)
def endTest(self, test):
for listener in self.listeners:
listener.endTest(test)
def addSuccess(self, test):
TestResult.addSuccess(self, test)
for listener in self.listeners:
listener.addSuccess(test)
def addError(self, test, err):
TestResult.addError(self, test, err)
for listener in self.listeners:
listener.addError(test, err)
def addFailure(self, test, err):
TestResult.addFailure(self, test, err)
for listener in self.listeners:
listener.addFailure(test, err)
def addListener(self, listener):
self.listeners.append(listener)
def removeListener(self, listener):
self.listeners.remove(listener)
@@ -462,6 +462,11 @@ runcfg.doctest.description=Python's doctests run configuration
runcfg.nosetests.display_name=Python's nosetests
runcfg.nosetests.description=Python's nosetests run configuration
### pytest run conf
runcfg.pytest.display_name=py.test
runcfg.pytest.description=py.test run configuration
### unittest run configuration
runcfg.unittest.display_name=Python's unittest
runcfg.unittest.description=Python's unittest run configuration
@@ -9,9 +9,6 @@ import com.jetbrains.python.psi.*;
import com.jetbrains.python.psi.impl.PyAugAssignmentStatementImpl;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.List;
/**
* User: catherine
*
@@ -52,7 +49,7 @@ public class AugmentedAssignmentQuickFix implements LocalQuickFix {
PyElementGenerator elementGenerator = PyElementGenerator.getInstance(project);
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append(target.getName()).append(" ").
stringBuilder.append(target.getText()).append(" ").
append(expression.getPsiOperator().getText()).append("= ").append(rightExpression.getText());
PyAugAssignmentStatementImpl augAssignment = elementGenerator.createFromText(LanguageLevel.getDefault(),
PyAugAssignmentStatementImpl.class, stringBuilder.toString());
@@ -60,6 +57,21 @@ public class AugmentedAssignmentQuickFix implements LocalQuickFix {
}
}
}
else if (rightExpression != null && rightExpression instanceof PyReferenceExpression) {
if (rightExpression.getName().equals(target.getName())) {
if (leftExpression instanceof PyNumericLiteralExpression ||
leftExpression instanceof PyStringLiteralExpression) {
PyElementGenerator elementGenerator = PyElementGenerator.getInstance(project);
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append(target.getText()).append(" ").
append(expression.getPsiOperator().getText()).append("= ").append(leftExpression.getText());
PyAugAssignmentStatementImpl augAssignment = elementGenerator.createFromText(LanguageLevel.getDefault(),
PyAugAssignmentStatementImpl.class, stringBuilder.toString());
statement.replace(augAssignment);
}
}
}
}
}
}
@@ -58,17 +58,36 @@ public class PyConvertLambdaToFunctionIntention extends BaseIntentionAction {
}
functionBuilder.statement("return " + body.getText());
PyFunction function = functionBuilder.buildFunction(project);
PyStatement statement = PsiTreeUtil.getParentOfType(lambdaExpression, PyStatement.class);
if (statement != null) {
PsiElement parentOfStatement = statement.getParent();
if (parentOfStatement != null)
function = (PyFunction)parentOfStatement.addBefore(function, statement);
PyFunction parentFunction = PsiTreeUtil.getTopmostParentOfType(lambdaExpression, PyFunction.class);
if (parentFunction != null ) {
PyClass parentClass = PsiTreeUtil.getTopmostParentOfType(parentFunction, PyClass.class);
if (parentClass != null) {
PsiElement classParent = parentClass.getParent();
function = (PyFunction)classParent.addBefore(function, parentClass);
} else {
PsiElement funcParent = parentFunction.getParent();
function = (PyFunction)funcParent.addBefore(function, parentFunction);
}
} else {
PyStatement statement = PsiTreeUtil.getTopmostParentOfType(lambdaExpression,
PyStatement.class);
if (statement != null) {
PsiElement statementParent = statement.getParent();
if (statementParent != null)
function = (PyFunction)statementParent.addBefore(function, statement);
}
}
function = CodeInsightUtilBase
.forcePsiPostprocessAndRestoreElement(function);
if (parent instanceof PyAssignmentStatement) {
parent.delete();
}
else {
PyElement parentScope = PsiTreeUtil.getParentOfType(lambdaExpression, PyFunction.class, PyClass.class, PyFile.class);
PyElement parentScope = PsiTreeUtil.getParentOfType(lambdaExpression, PyClass.class, PyFile.class);
final TemplateBuilder builder = TemplateBuilderFactory.getInstance().createTemplateBuilder(parentScope);
PsiElement functionName = function.getNameIdentifier();
functionName = CodeInsightUtilBase.forcePsiPostprocessAndRestoreElement(functionName);
@@ -5,7 +5,6 @@ import com.intellij.psi.PsiElementVisitor;
import com.jetbrains.python.PyBundle;
import com.jetbrains.python.PyTokenTypes;
import com.jetbrains.python.actions.AugmentedAssignmentQuickFix;
import com.jetbrains.python.actions.RedundantParenthesesQuickFix;
import com.jetbrains.python.psi.*;
import org.jetbrains.annotations.Nls;
import org.jetbrains.annotations.NotNull;
@@ -57,6 +56,18 @@ public class PyAugmentAssignmentInspection extends PyInspection {
}
}
}
else if (rightExpression != null && rightExpression instanceof PyReferenceExpression) {
if (rightExpression.getText().equals(target.getText())) {
if (leftExpression instanceof PyNumericLiteralExpression) {
PyElementType op = expression.getOperator();
if (op == PyTokenTypes.PLUS || op == PyTokenTypes.MINUS ||
op == PyTokenTypes.MULT || op == PyTokenTypes.DIV) {
AugmentedAssignmentQuickFix quickFix = new AugmentedAssignmentQuickFix();
registerProblem(node, "Assignment can be replaced with augmented assignment", quickFix);
}
}
}
}
}
}
}
@@ -31,6 +31,7 @@ import java.util.Set;
public class PythonTestConfigurationsModel implements ComboBoxModel {
public static final String PYTHONS_UNITTEST_NAME = PyBundle.message("runcfg.unittest.display_name");
public static final String PYTHONS_NOSETEST_NAME = PyBundle.message("runcfg.nosetests.display_name");
public static final String PY_TEST_NAME = PyBundle.message("runcfg.pytest.display_name");
private static final PythonTestConfigurationsModel INSTANCE = new PythonTestConfigurationsModel();
private final List<String> myConfigurationTypes = new ArrayList<String>();
@@ -33,7 +33,7 @@ public class PythonUnitTestConfigurationType extends ConfigurationTypeBase {
}
public RunConfiguration createTemplateConfiguration(Project project) {
myModel.addConfiguration(PyBundle.message("runcfg.unittest.display_name"), false);
myModel.addConfiguration(PythonTestConfigurationsModel.PYTHONS_UNITTEST_NAME, false);
return new PythonUnitTestRunConfiguration(new RunConfigurationModule(project), this, "");
}
}
@@ -4,6 +4,7 @@ import com.intellij.openapi.options.Configurable;
import com.intellij.openapi.options.ConfigurationException;
import com.intellij.openapi.options.NonDefaultProjectConfigurable;
import com.jetbrains.python.testing.nosetest.PythonNoseTestConfigurationProducer;
import com.jetbrains.python.testing.pytest.PyTestConfigurationProducer;
import org.jetbrains.annotations.Nls;
import javax.swing.*;
@@ -51,10 +52,17 @@ public class TestRunnerConfigurable implements Configurable, NonDefaultProjectCo
if (selectedItem.equals(PythonTestConfigurationsModel.PYTHONS_UNITTEST_NAME)) {
PythonUnitTestConfigurationProducer.getInstance(PythonUnitTestConfigurationProducer.class).setActive(true);
PythonNoseTestConfigurationProducer.getInstance(PythonNoseTestConfigurationProducer.class).setActive(false);
PyTestConfigurationProducer.getInstance(PyTestConfigurationProducer.class).setActive(false);
}
else if (selectedItem.equals(PythonTestConfigurationsModel.PYTHONS_NOSETEST_NAME)) {
PythonNoseTestConfigurationProducer.getInstance(PythonNoseTestConfigurationProducer.class).setActive(true);
PythonUnitTestConfigurationProducer.getInstance(PythonUnitTestConfigurationProducer.class).setActive(false);
PyTestConfigurationProducer.getInstance(PyTestConfigurationProducer.class).setActive(false);
}
else if (selectedItem.equals(PythonTestConfigurationsModel.PY_TEST_NAME)) {
PyTestConfigurationProducer.getInstance(PyTestConfigurationProducer.class).setActive(true);
PythonNoseTestConfigurationProducer.getInstance(PythonNoseTestConfigurationProducer.class).setActive(false);
PythonUnitTestConfigurationProducer.getInstance(PythonUnitTestConfigurationProducer.class).setActive(false);
}
}
});
@@ -58,7 +58,7 @@ public class PythonDocTestCommandLineState extends PythonTestCommandLineStateBas
break;
case TEST_FOLDER:
if (!myConfig.getPattern().isEmpty())
specs.add(myConfig.getFolderName() + "/" + ";" + myConfig.getPattern() + "$");
specs.add(myConfig.getFolderName() + "/" + ";" + myConfig.getPattern());
else
specs.add(myConfig.getFolderName() + "/");
// TODO[kate]:think about delimiter between folderName and Pattern
@@ -33,7 +33,7 @@ public class PythonNoseTestRunConfigurationType extends ConfigurationTypeBase {
}
public RunConfiguration createTemplateConfiguration(Project project) {
myModel.addConfiguration(PyBundle.message("runcfg.nosetests.display_name"), false);
myModel.addConfiguration(PythonTestConfigurationsModel.PYTHONS_NOSETEST_NAME, false);
return new PythonNoseTestRunConfiguration(new RunConfigurationModule(project), this, "");
}
}
@@ -29,6 +29,7 @@ import java.util.List;
public class PyTestConfigurationProducer extends RuntimeConfigurationProducer {
private PsiElement myPsiElement;
private boolean isActive = false;
public PyTestConfigurationProducer() {
super(ConfigurationTypeUtil.findConfigurationType(PyTestRunConfigurationType.class));
@@ -41,6 +42,7 @@ public class PyTestConfigurationProducer extends RuntimeConfigurationProducer {
@Override
protected RunnerAndConfigurationSettings createConfigurationByElement(Location location, ConfigurationContext context) {
if (!isActive) return null;
PsiElement element = location.getPsiElement();
PsiFileSystemItem file = element instanceof PsiDirectory ? (PsiDirectory)element : element.getContainingFile();
if (file == null) return null;
@@ -73,6 +75,7 @@ public class PyTestConfigurationProducer extends RuntimeConfigurationProducer {
configuration.setName(name + " in " + configuration.getName());
myPsiElement = pyFunction;
}
configuration.setName(configuration.suggestedName());
return result;
}
@@ -116,4 +119,7 @@ public class PyTestConfigurationProducer extends RuntimeConfigurationProducer {
}
return PREFERED;
}
public void setActive(boolean active) {
isActive = active;
}
}
@@ -106,4 +106,8 @@ public class PyTestRunConfiguration extends AbstractPythonRunConfiguration {
if (runner.exists()) return runner.getPath();
return null;
}
@Override
public String suggestedName() {
return "py.test in " + getName();
}
}
@@ -5,7 +5,9 @@ import com.intellij.execution.configurations.ConfigurationType;
import com.intellij.execution.configurations.RunConfiguration;
import com.intellij.execution.configurations.RunConfigurationModule;
import com.intellij.openapi.project.Project;
import com.jetbrains.python.PyBundle;
import com.jetbrains.python.PythonFileType;
import com.jetbrains.python.testing.PythonTestConfigurationsModel;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
@@ -17,11 +19,11 @@ public class PyTestRunConfigurationType implements ConfigurationType {
private final ConfigurationFactory myPyTestConfigurationFactory = new PyTestRunConfigurationFactory(this);
public String getDisplayName() {
return "py.test";
return PyBundle.message("runcfg.pytest.display_name");
}
public String getConfigurationTypeDescription() {
return "py.test";
return PyBundle.message("runcfg.pytest.description");
}
public Icon getIcon() {
@@ -39,11 +41,13 @@ public class PyTestRunConfigurationType implements ConfigurationType {
private static class PyTestRunConfigurationFactory extends ConfigurationFactory {
final private PythonTestConfigurationsModel myModel = PythonTestConfigurationsModel.getInstance();
protected PyTestRunConfigurationFactory(ConfigurationType type) {
super(type);
}
public RunConfiguration createTemplateConfiguration(Project project) {
myModel.addConfiguration(PythonTestConfigurationsModel.PY_TEST_NAME, false);
return new PyTestRunConfiguration("", new RunConfigurationModule(project), this);
}
}
@@ -0,0 +1,4 @@
class A:
x = 3
a = A()
<warning descr="Assignment can be replaced with augmented assignment">a.x = a.x +<caret> 1</warning>
@@ -0,0 +1,4 @@
class A:
x = 3
a = A()
a.x += 1
@@ -10,4 +10,6 @@ var_4 = 1
var_5 = var_5 + "string"
var_6 = var_6 + var_4
var_7 += 2
var_7 += 2
<warning descr="Assignment can be replaced with augmented assignment">var = 2 + var</warning> # PY-2482
@@ -179,6 +179,11 @@ public class PyQuickFixTest extends PyLightFixtureTestCase {
PyBundle.message("QFIX.augment.assignment"), true, true);
}
public void testAugmentAssignmentWithContext() { // PY-2481
doInspectionTest("AugmentAssignmentWithContext.py", PyAugmentAssignmentInspection.class,
PyBundle.message("QFIX.augment.assignment"), true, true);
}
public void testChainedComparisons() { // PY-1020
doInspectionTest("ChainedComparisons.py", PyChainedComparisonsInspection.class,
PyBundle.message("QFIX.chained.comparison"), true, true);