diff --git a/python/src/com/jetbrains/python/PyBundle.properties b/python/src/com/jetbrains/python/PyBundle.properties
index fa0cc1b32d22..93dab333a159 100644
--- a/python/src/com/jetbrains/python/PyBundle.properties
+++ b/python/src/com/jetbrains/python/PyBundle.properties
@@ -141,6 +141,8 @@ QFIX.NAME.rename.argument=Rename argument
QFIX.NAME.wrap.in.exception=Wrap with Exception call
+QFIX.NAME.make.list=Replace tuple with list
+
# Intentions: INTN
INTN.Family.convert.import.unqualify=Convert 'import module' to 'from module import'
INTN.Family.convert.import.qualify=Convert 'from module import' to 'import module'
diff --git a/python/src/com/jetbrains/python/inspections/PyTupleItemAssignmentInspection.java b/python/src/com/jetbrains/python/inspections/PyTupleItemAssignmentInspection.java
index 3416b5076ca4..79613f023770 100644
--- a/python/src/com/jetbrains/python/inspections/PyTupleItemAssignmentInspection.java
+++ b/python/src/com/jetbrains/python/inspections/PyTupleItemAssignmentInspection.java
@@ -20,6 +20,7 @@ import com.intellij.codeInspection.ProblemsHolder;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiElementVisitor;
import com.jetbrains.python.PyBundle;
+import com.jetbrains.python.inspections.quickfix.PyReplaceTupleWithListQuickFix;
import com.jetbrains.python.psi.PyAssignmentStatement;
import com.jetbrains.python.psi.PyExpression;
import com.jetbrains.python.psi.PyReferenceExpression;
@@ -64,7 +65,7 @@ public class PyTupleItemAssignmentInspection extends PyInspection {
PyExpression expression = (PyExpression)element;
PyType type = myTypeEvalContext.getType(expression);
if (type instanceof PyTupleType) {
- registerProblem(node, PyBundle.message("INSP.tuples.never.assign.items"));
+ registerProblem(node, PyBundle.message("INSP.tuples.never.assign.items"), new PyReplaceTupleWithListQuickFix());
}
}
}
diff --git a/python/src/com/jetbrains/python/inspections/quickfix/PyReplaceTupleWithListQuickFix.java b/python/src/com/jetbrains/python/inspections/quickfix/PyReplaceTupleWithListQuickFix.java
new file mode 100644
index 000000000000..ecb22c18ef14
--- /dev/null
+++ b/python/src/com/jetbrains/python/inspections/quickfix/PyReplaceTupleWithListQuickFix.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2000-2013 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.jetbrains.python.inspections.quickfix;
+
+import com.intellij.codeInspection.LocalQuickFix;
+import com.intellij.codeInspection.ProblemDescriptor;
+import com.intellij.openapi.project.Project;
+import com.intellij.psi.PsiElement;
+import com.jetbrains.python.PyBundle;
+import com.jetbrains.python.psi.*;
+import com.jetbrains.python.psi.resolve.PyResolveContext;
+import org.jetbrains.annotations.NotNull;
+
+public class PyReplaceTupleWithListQuickFix implements LocalQuickFix {
+ @NotNull
+ @Override
+ public String getName() {
+ return PyBundle.message("QFIX.NAME.make.list");
+ }
+
+ @NotNull
+ @Override
+ public String getFamilyName() {
+ return getName();
+ }
+
+ @Override
+ public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
+ PsiElement element = descriptor.getPsiElement();
+ assert element instanceof PyAssignmentStatement;
+ PyExpression[] targets = ((PyAssignmentStatement)element).getTargets();
+ if (targets.length == 1 && targets[0] instanceof PySubscriptionExpression) {
+ PySubscriptionExpression subscriptionExpression = (PySubscriptionExpression)targets[0];
+ if (subscriptionExpression.getOperand() instanceof PyReferenceExpression) {
+ PyReferenceExpression referenceExpression = (PyReferenceExpression)subscriptionExpression.getOperand();
+ element = referenceExpression.followAssignmentsChain(PyResolveContext.defaultContext()).getElement();
+ if (element instanceof PyParenthesizedExpression) {
+ final PyExpression expression = ((PyParenthesizedExpression)element).getContainedExpression();
+ replaceWithListLiteral(element, (PyTupleExpression)expression);
+ }
+ else if (element instanceof PyTupleExpression) {
+ replaceWithListLiteral(element, (PyTupleExpression)element);
+ }
+ }
+ }
+ }
+
+ private static void replaceWithListLiteral(PsiElement element, PyTupleExpression expression) {
+ final String expressionText = expression.getElements().length == 0 ? "" :expression.getText();
+ final PyExpression literal = PyElementGenerator.getInstance(element.getProject()).
+ createExpressionFromText(LanguageLevel.forElement(element),
+ "[" + expressionText + "]");
+ element.replace(literal);
+ }
+}
diff --git a/python/testData/quickFixes/PyReplaceTupleWithListQuickFixTest/empty.py b/python/testData/quickFixes/PyReplaceTupleWithListQuickFixTest/empty.py
new file mode 100644
index 000000000000..fdb02322d363
--- /dev/null
+++ b/python/testData/quickFixes/PyReplaceTupleWithListQuickFixTest/empty.py
@@ -0,0 +1,2 @@
+a = ()
+a[0] = 3
\ No newline at end of file
diff --git a/python/testData/quickFixes/PyReplaceTupleWithListQuickFixTest/empty_after.py b/python/testData/quickFixes/PyReplaceTupleWithListQuickFixTest/empty_after.py
new file mode 100644
index 000000000000..bb7e190fe5fa
--- /dev/null
+++ b/python/testData/quickFixes/PyReplaceTupleWithListQuickFixTest/empty_after.py
@@ -0,0 +1,2 @@
+a = []
+a[0] = 3
\ No newline at end of file
diff --git a/python/testData/quickFixes/PyReplaceTupleWithListQuickFixTest/parenthesized.py b/python/testData/quickFixes/PyReplaceTupleWithListQuickFixTest/parenthesized.py
new file mode 100644
index 000000000000..35c7f439f844
--- /dev/null
+++ b/python/testData/quickFixes/PyReplaceTupleWithListQuickFixTest/parenthesized.py
@@ -0,0 +1,2 @@
+a = ("11",)
+a[0] = 3
\ No newline at end of file
diff --git a/python/testData/quickFixes/PyReplaceTupleWithListQuickFixTest/parenthesized_after.py b/python/testData/quickFixes/PyReplaceTupleWithListQuickFixTest/parenthesized_after.py
new file mode 100644
index 000000000000..7e86b06cd032
--- /dev/null
+++ b/python/testData/quickFixes/PyReplaceTupleWithListQuickFixTest/parenthesized_after.py
@@ -0,0 +1,2 @@
+a = ["11", ]
+a[0] = 3
\ No newline at end of file
diff --git a/python/testData/quickFixes/PyReplaceTupleWithListQuickFixTest/tupleExpression.py b/python/testData/quickFixes/PyReplaceTupleWithListQuickFixTest/tupleExpression.py
new file mode 100644
index 000000000000..02325e4ebeb4
--- /dev/null
+++ b/python/testData/quickFixes/PyReplaceTupleWithListQuickFixTest/tupleExpression.py
@@ -0,0 +1,2 @@
+a = "11",
+a[0] = 3
\ No newline at end of file
diff --git a/python/testData/quickFixes/PyReplaceTupleWithListQuickFixTest/tupleExpression_after.py b/python/testData/quickFixes/PyReplaceTupleWithListQuickFixTest/tupleExpression_after.py
new file mode 100644
index 000000000000..7e86b06cd032
--- /dev/null
+++ b/python/testData/quickFixes/PyReplaceTupleWithListQuickFixTest/tupleExpression_after.py
@@ -0,0 +1,2 @@
+a = ["11", ]
+a[0] = 3
\ No newline at end of file
diff --git a/python/testSrc/com/jetbrains/python/quickFixes/PyReplaceTupleWithListQuickFixTest.java b/python/testSrc/com/jetbrains/python/quickFixes/PyReplaceTupleWithListQuickFixTest.java
new file mode 100644
index 000000000000..3a911f29c5df
--- /dev/null
+++ b/python/testSrc/com/jetbrains/python/quickFixes/PyReplaceTupleWithListQuickFixTest.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2000-2013 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.jetbrains.python.quickFixes;
+
+import com.intellij.testFramework.TestDataPath;
+import com.jetbrains.python.PyBundle;
+import com.jetbrains.python.PyQuickFixTestCase;
+import com.jetbrains.python.inspections.PyTupleItemAssignmentInspection;
+
+@TestDataPath("$CONTENT_ROOT/../testData/quickFixes/PyReplaceTupleWithListQuickFixTest/")
+public class PyReplaceTupleWithListQuickFixTest extends PyQuickFixTestCase {
+
+ public void testParenthesized() {
+ doQuickFixTest(PyTupleItemAssignmentInspection.class, PyBundle.message("QFIX.NAME.make.list"));
+ }
+
+ public void testEmpty() {
+ doQuickFixTest(PyTupleItemAssignmentInspection.class, PyBundle.message("QFIX.NAME.make.list"));
+ }
+
+ public void testTupleExpression() {
+ doQuickFixTest(PyTupleItemAssignmentInspection.class, PyBundle.message("QFIX.NAME.make.list"));
+ }
+
+}