diff --git a/python/resources/intentionDescriptions/PyConvertLiteralToListIntention/after.py.template b/python/resources/intentionDescriptions/PyConvertLiteralToListIntention/after.py.template
new file mode 100644
index 000000000000..e14da11b83b8
--- /dev/null
+++ b/python/resources/intentionDescriptions/PyConvertLiteralToListIntention/after.py.template
@@ -0,0 +1,2 @@
+[1, 2, 3]
+[a, b] = [x, y]
\ No newline at end of file
diff --git a/python/resources/intentionDescriptions/PyConvertLiteralToListIntention/before.py.template b/python/resources/intentionDescriptions/PyConvertLiteralToListIntention/before.py.template
new file mode 100644
index 000000000000..19d36a5eeabf
--- /dev/null
+++ b/python/resources/intentionDescriptions/PyConvertLiteralToListIntention/before.py.template
@@ -0,0 +1,2 @@
+1, 2, 3
+a, b = {x, y}
\ No newline at end of file
diff --git a/python/resources/intentionDescriptions/PyConvertLiteralToListIntention/description.html b/python/resources/intentionDescriptions/PyConvertLiteralToListIntention/description.html
new file mode 100644
index 000000000000..94fcd390a899
--- /dev/null
+++ b/python/resources/intentionDescriptions/PyConvertLiteralToListIntention/description.html
@@ -0,0 +1,7 @@
+
+
+
+ This intention converts tuples and set literals to list literals.
+
+
+
\ No newline at end of file
diff --git a/python/resources/intentionDescriptions/PyConvertLiteralToSetIntention/after.py.template b/python/resources/intentionDescriptions/PyConvertLiteralToSetIntention/after.py.template
new file mode 100644
index 000000000000..66fed7400336
--- /dev/null
+++ b/python/resources/intentionDescriptions/PyConvertLiteralToSetIntention/after.py.template
@@ -0,0 +1,2 @@
+{1, 2, 3}
+a, b = {x, y}
\ No newline at end of file
diff --git a/python/resources/intentionDescriptions/PyConvertLiteralToSetIntention/before.py.template b/python/resources/intentionDescriptions/PyConvertLiteralToSetIntention/before.py.template
new file mode 100644
index 000000000000..cf7b045c426c
--- /dev/null
+++ b/python/resources/intentionDescriptions/PyConvertLiteralToSetIntention/before.py.template
@@ -0,0 +1,2 @@
+1, 2, 3
+a, b = [x, y]
\ No newline at end of file
diff --git a/python/resources/intentionDescriptions/PyConvertLiteralToSetIntention/description.html b/python/resources/intentionDescriptions/PyConvertLiteralToSetIntention/description.html
new file mode 100644
index 000000000000..f97323e11a0a
--- /dev/null
+++ b/python/resources/intentionDescriptions/PyConvertLiteralToSetIntention/description.html
@@ -0,0 +1,7 @@
+
+
+
+ This intention converts tuples and list literals to set literals.
+
+
+
\ No newline at end of file
diff --git a/python/resources/intentionDescriptions/PyConvertLiteralToTupleIntention/after.py.template b/python/resources/intentionDescriptions/PyConvertLiteralToTupleIntention/after.py.template
new file mode 100644
index 000000000000..f49faa060aae
--- /dev/null
+++ b/python/resources/intentionDescriptions/PyConvertLiteralToTupleIntention/after.py.template
@@ -0,0 +1,2 @@
+(1, 2, 3)
+a, b = (x, y)
\ No newline at end of file
diff --git a/python/resources/intentionDescriptions/PyConvertLiteralToTupleIntention/before.py.template b/python/resources/intentionDescriptions/PyConvertLiteralToTupleIntention/before.py.template
new file mode 100644
index 000000000000..7dc9ec397e76
--- /dev/null
+++ b/python/resources/intentionDescriptions/PyConvertLiteralToTupleIntention/before.py.template
@@ -0,0 +1,2 @@
+[1, 2, 3]
+a, b = {x, y}
\ No newline at end of file
diff --git a/python/resources/intentionDescriptions/PyConvertLiteralToTupleIntention/description.html b/python/resources/intentionDescriptions/PyConvertLiteralToTupleIntention/description.html
new file mode 100644
index 000000000000..2aeb980151ca
--- /dev/null
+++ b/python/resources/intentionDescriptions/PyConvertLiteralToTupleIntention/description.html
@@ -0,0 +1,7 @@
+
+
+
+ This intention converts list literals and set literals to tuples.
+
+
+
\ No newline at end of file
diff --git a/python/src/META-INF/python-core.xml b/python/src/META-INF/python-core.xml
index addd76688e70..8ac1ecdb1ab6 100644
--- a/python/src/META-INF/python-core.xml
+++ b/python/src/META-INF/python-core.xml
@@ -258,6 +258,21 @@
Python
+
+ com.jetbrains.python.codeInsight.intentions.PyConvertLiteralToTupleIntention
+ Python
+
+
+
+ com.jetbrains.python.codeInsight.intentions.PyConvertLiteralToListIntention
+ Python
+
+
+
+ com.jetbrains.python.codeInsight.intentions.PyConvertLiteralToSetIntention
+ Python
+
+
com.jetbrains.python.codeInsight.intentions.PyTransformConditionalExpressionIntention
Python
diff --git a/python/src/com/jetbrains/python/PyBundle.properties b/python/src/com/jetbrains/python/PyBundle.properties
index e0f3b62a598c..554e85283417 100644
--- a/python/src/com/jetbrains/python/PyBundle.properties
+++ b/python/src/com/jetbrains/python/PyBundle.properties
@@ -237,6 +237,9 @@ INTN.convert.variadic.param=Convert from variadic to normal parameter(s)
# PyConvertTripleQuotedStringIntention
INTN.triple.quoted.string=Convert triple-quoted string to single-quoted string
+INTN.convert.collection.literal.family=Convert collection to {0}
+INTN.convert.collection.literal.text=Convert {0} to {1}
+
# PyTransformConditionalExpressionIntention
INTN.transform.into.if.else.statement=Transform conditional expression into if/else statement
diff --git a/python/src/com/jetbrains/python/codeInsight/intentions/PyBaseConvertCollectionLiteralIntention.java b/python/src/com/jetbrains/python/codeInsight/intentions/PyBaseConvertCollectionLiteralIntention.java
new file mode 100644
index 000000000000..0ac0409edf1f
--- /dev/null
+++ b/python/src/com/jetbrains/python/codeInsight/intentions/PyBaseConvertCollectionLiteralIntention.java
@@ -0,0 +1,153 @@
+/*
+ * Copyright 2000-2015 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.jetbrains.python.codeInsight.intentions;
+
+import com.intellij.codeInsight.intention.impl.BaseIntentionAction;
+import com.intellij.openapi.editor.Editor;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.Condition;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiFile;
+import com.intellij.psi.util.PsiTreeUtil;
+import com.intellij.util.IncorrectOperationException;
+import com.jetbrains.python.PyBundle;
+import com.jetbrains.python.PyTokenTypes;
+import com.jetbrains.python.psi.*;
+import org.jetbrains.annotations.Nls;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import static com.jetbrains.python.psi.PyUtil.as;
+
+/**
+ * @author Mikhail Golubev
+ */
+public abstract class PyBaseConvertCollectionLiteralIntention extends BaseIntentionAction {
+ private final Class extends PySequenceExpression> myTargetCollectionClass;
+ private final String myTargetCollectionName;
+ private final String myRightBrace;
+ private final String myLeftBrace;
+
+ public PyBaseConvertCollectionLiteralIntention(@NotNull Class extends PySequenceExpression> targetCollectionClass,
+ @NotNull String targetCollectionName,
+ @NotNull String leftBrace, @NotNull String rightBrace) {
+ myTargetCollectionClass = targetCollectionClass;
+ myTargetCollectionName = targetCollectionName;
+ myLeftBrace = leftBrace;
+ myRightBrace = rightBrace;
+ }
+
+ @Nls
+ @NotNull
+ @Override
+ public String getFamilyName() {
+ return PyBundle.message("INTN.convert.collection.literal.family", myTargetCollectionName);
+ }
+
+ @Override
+ public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) {
+ if (!(file instanceof PyFile)) {
+ return false;
+ }
+ final PySequenceExpression literal = findCollectionLiteralUnderCaret(editor, file);
+ if (myTargetCollectionClass.isInstance(literal)) {
+ return false;
+ }
+ if (literal instanceof PyTupleExpression) {
+ setText(PyBundle.message("INTN.convert.collection.literal.text", "tuple", myTargetCollectionName));
+ }
+ else if (literal instanceof PyListLiteralExpression) {
+ setText(PyBundle.message("INTN.convert.collection.literal.text", "list", myTargetCollectionName));
+ }
+ else if (literal instanceof PySetLiteralExpression) {
+ setText(PyBundle.message("INTN.convert.collection.literal.text", "set", myTargetCollectionName));
+ }
+ else {
+ return false;
+ }
+ return isAvailableForCollection(literal);
+ }
+
+ protected boolean isAvailableForCollection(PySequenceExpression literal) {
+ return true;
+ }
+
+ @Override
+ public void invoke(@NotNull Project project, Editor editor, PsiFile file) throws IncorrectOperationException {
+ final PySequenceExpression literal = findCollectionLiteralUnderCaret(editor, file);
+ assert literal != null;
+
+ final PsiElement replacedElement;
+ if (literal instanceof PyTupleExpression && literal.getParent() instanceof PyParenthesizedExpression) {
+ replacedElement = literal.getParent();
+ }
+ else {
+ replacedElement = literal;
+ }
+
+ final PyElementGenerator elementGenerator = PyElementGenerator.getInstance(project);
+ final PyExpression newLiteral = elementGenerator.createExpressionFromText(LanguageLevel.forElement(file),
+ myLeftBrace + stripLiteralBraces(literal) + myRightBrace);
+ replacedElement.replace(newLiteral);
+ }
+
+ @NotNull
+ private static String stripLiteralBraces(@NotNull PySequenceExpression literal) {
+ if (literal instanceof PyTupleExpression) {
+ return literal.getText().trim();
+ }
+
+ final PsiElement firstChild = literal.getFirstChild();
+
+ final String replacedText = literal.getText();
+ final int contentStartOffset;
+ if (PyTokenTypes.OPEN_BRACES.contains(firstChild.getNode().getElementType())) {
+ contentStartOffset = firstChild.getTextLength();
+ }
+ else {
+ contentStartOffset = 0;
+ }
+
+ final PsiElement lastChild = literal.getLastChild();
+ final int contentEndOffset;
+ if (PyTokenTypes.CLOSE_BRACES.contains(lastChild.getNode().getElementType())) {
+ contentEndOffset = replacedText.length() - lastChild.getTextLength();
+ }
+ else {
+ contentEndOffset = replacedText.length();
+ }
+
+ return literal.getText().substring(contentStartOffset, contentEndOffset).trim();
+ }
+
+ @Nullable
+ private static PySequenceExpression findCollectionLiteralUnderCaret(@NotNull Editor editor, @NotNull PsiFile psiFile) {
+ final int caretOffset = editor.getCaretModel().getOffset();
+ final PsiElement curElem = psiFile.findElementAt(caretOffset);
+ final PySequenceExpression seqExpr = PsiTreeUtil.getParentOfType(curElem, PySequenceExpression.class);
+ if (seqExpr != null) {
+ return seqExpr;
+ }
+ final PyParenthesizedExpression paren = (PyParenthesizedExpression)PsiTreeUtil.findFirstParent(curElem, new Condition() {
+ @Override
+ public boolean value(PsiElement element) {
+ final PyParenthesizedExpression parenthesizedExpr = as(element, PyParenthesizedExpression.class);
+ return parenthesizedExpr != null && parenthesizedExpr.getContainedExpression() instanceof PyTupleExpression;
+ }
+ });
+ return paren != null ? ((PyTupleExpression)paren.getContainedExpression()) : null;
+ }
+}
diff --git a/python/src/com/jetbrains/python/codeInsight/intentions/PyConvertLiteralToListIntention.java b/python/src/com/jetbrains/python/codeInsight/intentions/PyConvertLiteralToListIntention.java
new file mode 100644
index 000000000000..a59479a40b2a
--- /dev/null
+++ b/python/src/com/jetbrains/python/codeInsight/intentions/PyConvertLiteralToListIntention.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2000-2015 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.jetbrains.python.codeInsight.intentions;
+
+import com.jetbrains.python.psi.PyListLiteralExpression;
+
+/**
+ * @author Mikhail Golubev
+ */
+public class PyConvertLiteralToListIntention extends PyBaseConvertCollectionLiteralIntention {
+ public PyConvertLiteralToListIntention() {
+ super(PyListLiteralExpression.class, "list", "[", "]");
+ }
+}
diff --git a/python/src/com/jetbrains/python/codeInsight/intentions/PyConvertLiteralToSetIntention.java b/python/src/com/jetbrains/python/codeInsight/intentions/PyConvertLiteralToSetIntention.java
new file mode 100644
index 000000000000..0f21128c657b
--- /dev/null
+++ b/python/src/com/jetbrains/python/codeInsight/intentions/PyConvertLiteralToSetIntention.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2000-2015 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.jetbrains.python.codeInsight.intentions;
+
+import com.intellij.openapi.util.Condition;
+import com.intellij.util.containers.ContainerUtil;
+import com.jetbrains.python.psi.*;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author Mikhail Golubev
+ */
+public class PyConvertLiteralToSetIntention extends PyBaseConvertCollectionLiteralIntention {
+ public PyConvertLiteralToSetIntention() {
+ super(PySetLiteralExpression.class, "set", "{", "}");
+ }
+
+ @Override
+ protected boolean isAvailableForCollection(PySequenceExpression literal) {
+ return LanguageLevel.forElement(literal).isAtLeast(LanguageLevel.PYTHON27) && !isInTargetPosition(literal);
+ }
+
+ private static boolean isInTargetPosition(@NotNull final PySequenceExpression sequenceLiteral) {
+ return ContainerUtil.exists(sequenceLiteral.getElements(), new Condition() {
+ @Override
+ public boolean value(PyExpression expression) {
+ return expression instanceof PyTargetExpression;
+ }
+ });
+ }
+}
diff --git a/python/src/com/jetbrains/python/codeInsight/intentions/PyConvertLiteralToTupleIntention.java b/python/src/com/jetbrains/python/codeInsight/intentions/PyConvertLiteralToTupleIntention.java
new file mode 100644
index 000000000000..91a62f7dc9ee
--- /dev/null
+++ b/python/src/com/jetbrains/python/codeInsight/intentions/PyConvertLiteralToTupleIntention.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2000-2015 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.jetbrains.python.codeInsight.intentions;
+
+import com.jetbrains.python.psi.PyTupleExpression;
+
+/**
+ * @author Mikhail Golubev
+ */
+public class PyConvertLiteralToTupleIntention extends PyBaseConvertCollectionLiteralIntention {
+ public PyConvertLiteralToTupleIntention() {
+ super(PyTupleExpression.class, "tuple", "(", ")");
+ }
+}
diff --git a/python/testData/intentions/PyConvertCollectionLiteralIntentionTest/convertListToSet.py b/python/testData/intentions/PyConvertCollectionLiteralIntentionTest/convertListToSet.py
new file mode 100644
index 000000000000..d80f426637a5
--- /dev/null
+++ b/python/testData/intentions/PyConvertCollectionLiteralIntentionTest/convertListToSet.py
@@ -0,0 +1 @@
+xs = [1, 2]
\ No newline at end of file
diff --git a/python/testData/intentions/PyConvertCollectionLiteralIntentionTest/convertListToSet_after.py b/python/testData/intentions/PyConvertCollectionLiteralIntentionTest/convertListToSet_after.py
new file mode 100644
index 000000000000..dce932f47e72
--- /dev/null
+++ b/python/testData/intentions/PyConvertCollectionLiteralIntentionTest/convertListToSet_after.py
@@ -0,0 +1 @@
+xs = {1, 2}
\ No newline at end of file
diff --git a/python/testData/intentions/PyConvertCollectionLiteralIntentionTest/convertListToTuple.py b/python/testData/intentions/PyConvertCollectionLiteralIntentionTest/convertListToTuple.py
new file mode 100644
index 000000000000..d80f426637a5
--- /dev/null
+++ b/python/testData/intentions/PyConvertCollectionLiteralIntentionTest/convertListToTuple.py
@@ -0,0 +1 @@
+xs = [1, 2]
\ No newline at end of file
diff --git a/python/testData/intentions/PyConvertCollectionLiteralIntentionTest/convertListToTuple_after.py b/python/testData/intentions/PyConvertCollectionLiteralIntentionTest/convertListToTuple_after.py
new file mode 100644
index 000000000000..be8e91d871a6
--- /dev/null
+++ b/python/testData/intentions/PyConvertCollectionLiteralIntentionTest/convertListToTuple_after.py
@@ -0,0 +1 @@
+xs = (1, 2)
\ No newline at end of file
diff --git a/python/testData/intentions/PyConvertCollectionLiteralIntentionTest/convertListWithoutClosingBracketToTuple.py b/python/testData/intentions/PyConvertCollectionLiteralIntentionTest/convertListWithoutClosingBracketToTuple.py
new file mode 100644
index 000000000000..3e32a955febb
--- /dev/null
+++ b/python/testData/intentions/PyConvertCollectionLiteralIntentionTest/convertListWithoutClosingBracketToTuple.py
@@ -0,0 +1 @@
+xs = [1, 2
\ No newline at end of file
diff --git a/python/testData/intentions/PyConvertCollectionLiteralIntentionTest/convertListWithoutClosingBracketToTuple_after.py b/python/testData/intentions/PyConvertCollectionLiteralIntentionTest/convertListWithoutClosingBracketToTuple_after.py
new file mode 100644
index 000000000000..be8e91d871a6
--- /dev/null
+++ b/python/testData/intentions/PyConvertCollectionLiteralIntentionTest/convertListWithoutClosingBracketToTuple_after.py
@@ -0,0 +1 @@
+xs = (1, 2)
\ No newline at end of file
diff --git a/python/testData/intentions/PyConvertCollectionLiteralIntentionTest/convertParenthesizedTupleToList.py b/python/testData/intentions/PyConvertCollectionLiteralIntentionTest/convertParenthesizedTupleToList.py
new file mode 100644
index 000000000000..ee5237ceedbf
--- /dev/null
+++ b/python/testData/intentions/PyConvertCollectionLiteralIntentionTest/convertParenthesizedTupleToList.py
@@ -0,0 +1 @@
+xs = (1, 2)
\ No newline at end of file
diff --git a/python/testData/intentions/PyConvertCollectionLiteralIntentionTest/convertParenthesizedTupleToList_after.py b/python/testData/intentions/PyConvertCollectionLiteralIntentionTest/convertParenthesizedTupleToList_after.py
new file mode 100644
index 000000000000..e699c4d4ccd3
--- /dev/null
+++ b/python/testData/intentions/PyConvertCollectionLiteralIntentionTest/convertParenthesizedTupleToList_after.py
@@ -0,0 +1 @@
+xs = [1, 2]
\ No newline at end of file
diff --git a/python/testData/intentions/PyConvertCollectionLiteralIntentionTest/convertParenthesizedTupleToSet.py b/python/testData/intentions/PyConvertCollectionLiteralIntentionTest/convertParenthesizedTupleToSet.py
new file mode 100644
index 000000000000..ee5237ceedbf
--- /dev/null
+++ b/python/testData/intentions/PyConvertCollectionLiteralIntentionTest/convertParenthesizedTupleToSet.py
@@ -0,0 +1 @@
+xs = (1, 2)
\ No newline at end of file
diff --git a/python/testData/intentions/PyConvertCollectionLiteralIntentionTest/convertParenthesizedTupleToSet_after.py b/python/testData/intentions/PyConvertCollectionLiteralIntentionTest/convertParenthesizedTupleToSet_after.py
new file mode 100644
index 000000000000..dce932f47e72
--- /dev/null
+++ b/python/testData/intentions/PyConvertCollectionLiteralIntentionTest/convertParenthesizedTupleToSet_after.py
@@ -0,0 +1 @@
+xs = {1, 2}
\ No newline at end of file
diff --git a/python/testData/intentions/PyConvertCollectionLiteralIntentionTest/convertSetToList.py b/python/testData/intentions/PyConvertCollectionLiteralIntentionTest/convertSetToList.py
new file mode 100644
index 000000000000..334e1d5bdc0c
--- /dev/null
+++ b/python/testData/intentions/PyConvertCollectionLiteralIntentionTest/convertSetToList.py
@@ -0,0 +1 @@
+xs = {1, 2}
\ No newline at end of file
diff --git a/python/testData/intentions/PyConvertCollectionLiteralIntentionTest/convertSetToList_after.py b/python/testData/intentions/PyConvertCollectionLiteralIntentionTest/convertSetToList_after.py
new file mode 100644
index 000000000000..e699c4d4ccd3
--- /dev/null
+++ b/python/testData/intentions/PyConvertCollectionLiteralIntentionTest/convertSetToList_after.py
@@ -0,0 +1 @@
+xs = [1, 2]
\ No newline at end of file
diff --git a/python/testData/intentions/PyConvertCollectionLiteralIntentionTest/convertSetToTuple.py b/python/testData/intentions/PyConvertCollectionLiteralIntentionTest/convertSetToTuple.py
new file mode 100644
index 000000000000..0a46986d7aae
--- /dev/null
+++ b/python/testData/intentions/PyConvertCollectionLiteralIntentionTest/convertSetToTuple.py
@@ -0,0 +1 @@
+xs = {1, 2}
\ No newline at end of file
diff --git a/python/testData/intentions/PyConvertCollectionLiteralIntentionTest/convertSetToTuple_after.py b/python/testData/intentions/PyConvertCollectionLiteralIntentionTest/convertSetToTuple_after.py
new file mode 100644
index 000000000000..be8e91d871a6
--- /dev/null
+++ b/python/testData/intentions/PyConvertCollectionLiteralIntentionTest/convertSetToTuple_after.py
@@ -0,0 +1 @@
+xs = (1, 2)
\ No newline at end of file
diff --git a/python/testData/intentions/PyConvertCollectionLiteralIntentionTest/convertSetWithoutClosingBraceToTuple.py b/python/testData/intentions/PyConvertCollectionLiteralIntentionTest/convertSetWithoutClosingBraceToTuple.py
new file mode 100644
index 000000000000..81ea5ac6ba89
--- /dev/null
+++ b/python/testData/intentions/PyConvertCollectionLiteralIntentionTest/convertSetWithoutClosingBraceToTuple.py
@@ -0,0 +1 @@
+xs = {1, 2
\ No newline at end of file
diff --git a/python/testData/intentions/PyConvertCollectionLiteralIntentionTest/convertSetWithoutClosingBraceToTuple_after.py b/python/testData/intentions/PyConvertCollectionLiteralIntentionTest/convertSetWithoutClosingBraceToTuple_after.py
new file mode 100644
index 000000000000..be8e91d871a6
--- /dev/null
+++ b/python/testData/intentions/PyConvertCollectionLiteralIntentionTest/convertSetWithoutClosingBraceToTuple_after.py
@@ -0,0 +1 @@
+xs = (1, 2)
\ No newline at end of file
diff --git a/python/testData/intentions/PyConvertCollectionLiteralIntentionTest/convertTupleToSetNotAvailableInAssignmentTarget.py b/python/testData/intentions/PyConvertCollectionLiteralIntentionTest/convertTupleToSetNotAvailableInAssignmentTarget.py
new file mode 100644
index 000000000000..8ee25d153228
--- /dev/null
+++ b/python/testData/intentions/PyConvertCollectionLiteralIntentionTest/convertTupleToSetNotAvailableInAssignmentTarget.py
@@ -0,0 +1 @@
+x, y = 1, 2
\ No newline at end of file
diff --git a/python/testData/intentions/PyConvertCollectionLiteralIntentionTest/convertTupleToSetNotAvailableInComprehension.py b/python/testData/intentions/PyConvertCollectionLiteralIntentionTest/convertTupleToSetNotAvailableInComprehension.py
new file mode 100644
index 000000000000..f6c3a5c4c265
--- /dev/null
+++ b/python/testData/intentions/PyConvertCollectionLiteralIntentionTest/convertTupleToSetNotAvailableInComprehension.py
@@ -0,0 +1 @@
+xs = [x for x, y in zip('foo', range(3))]
\ No newline at end of file
diff --git a/python/testData/intentions/PyConvertCollectionLiteralIntentionTest/convertTupleToSetNotAvailableInForLoop.py b/python/testData/intentions/PyConvertCollectionLiteralIntentionTest/convertTupleToSetNotAvailableInForLoop.py
new file mode 100644
index 000000000000..9d66f34b6922
--- /dev/null
+++ b/python/testData/intentions/PyConvertCollectionLiteralIntentionTest/convertTupleToSetNotAvailableInForLoop.py
@@ -0,0 +1,2 @@
+for x, y in zip('foo', range(3)):
+ pass
\ No newline at end of file
diff --git a/python/testData/intentions/PyConvertCollectionLiteralIntentionTest/convertTupleToSetNotAvailableWithoutSetLiterals.py b/python/testData/intentions/PyConvertCollectionLiteralIntentionTest/convertTupleToSetNotAvailableWithoutSetLiterals.py
new file mode 100644
index 000000000000..ee5237ceedbf
--- /dev/null
+++ b/python/testData/intentions/PyConvertCollectionLiteralIntentionTest/convertTupleToSetNotAvailableWithoutSetLiterals.py
@@ -0,0 +1 @@
+xs = (1, 2)
\ No newline at end of file
diff --git a/python/testData/intentions/PyConvertCollectionLiteralIntentionTest/convertTupleWithoutClosingParenthesisToList.py b/python/testData/intentions/PyConvertCollectionLiteralIntentionTest/convertTupleWithoutClosingParenthesisToList.py
new file mode 100644
index 000000000000..45ae094156e1
--- /dev/null
+++ b/python/testData/intentions/PyConvertCollectionLiteralIntentionTest/convertTupleWithoutClosingParenthesisToList.py
@@ -0,0 +1 @@
+xs = (1, 2
\ No newline at end of file
diff --git a/python/testData/intentions/PyConvertCollectionLiteralIntentionTest/convertTupleWithoutClosingParenthesisToList_after.py b/python/testData/intentions/PyConvertCollectionLiteralIntentionTest/convertTupleWithoutClosingParenthesisToList_after.py
new file mode 100644
index 000000000000..e699c4d4ccd3
--- /dev/null
+++ b/python/testData/intentions/PyConvertCollectionLiteralIntentionTest/convertTupleWithoutClosingParenthesisToList_after.py
@@ -0,0 +1 @@
+xs = [1, 2]
\ No newline at end of file
diff --git a/python/testData/intentions/PyConvertCollectionLiteralIntentionTest/convertTupleWithoutParenthesesToList.py b/python/testData/intentions/PyConvertCollectionLiteralIntentionTest/convertTupleWithoutParenthesesToList.py
new file mode 100644
index 000000000000..81809899de9e
--- /dev/null
+++ b/python/testData/intentions/PyConvertCollectionLiteralIntentionTest/convertTupleWithoutParenthesesToList.py
@@ -0,0 +1 @@
+xs = 1, 2
diff --git a/python/testData/intentions/PyConvertCollectionLiteralIntentionTest/convertTupleWithoutParenthesesToList_after.py b/python/testData/intentions/PyConvertCollectionLiteralIntentionTest/convertTupleWithoutParenthesesToList_after.py
new file mode 100644
index 000000000000..2bd93ce9f2e2
--- /dev/null
+++ b/python/testData/intentions/PyConvertCollectionLiteralIntentionTest/convertTupleWithoutParenthesesToList_after.py
@@ -0,0 +1 @@
+xs = [1, 2]
diff --git a/python/testSrc/com/jetbrains/python/intentions/PyConvertCollectionLiteralIntentionTest.java b/python/testSrc/com/jetbrains/python/intentions/PyConvertCollectionLiteralIntentionTest.java
new file mode 100644
index 000000000000..0e50c05e8d1f
--- /dev/null
+++ b/python/testSrc/com/jetbrains/python/intentions/PyConvertCollectionLiteralIntentionTest.java
@@ -0,0 +1,106 @@
+/*
+ * Copyright 2000-2015 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.jetbrains.python.intentions;
+
+import com.jetbrains.python.PyBundle;
+import com.jetbrains.python.psi.LanguageLevel;
+
+/**
+ * @author Mikhail Golubev
+ */
+public class PyConvertCollectionLiteralIntentionTest extends PyIntentionTestCase {
+
+ private static final String CONVERT_TUPLE_TO_LIST = PyBundle.message("INTN.convert.collection.literal.text", "tuple", "list");
+ private static final String CONVERT_TUPLE_TO_SET = PyBundle.message("INTN.convert.collection.literal.text", "tuple", "set");
+ private static final String CONVERT_LIST_TO_TUPLE = PyBundle.message("INTN.convert.collection.literal.text", "list", "tuple");
+ private static final String CONVERT_LIST_TO_SET = PyBundle.message("INTN.convert.collection.literal.text", "list", "set");
+ private static final String CONVERT_SET_TO_TUPLE = PyBundle.message("INTN.convert.collection.literal.text", "set", "tuple");
+ private static final String CONVERT_SET_TO_LIST = PyBundle.message("INTN.convert.collection.literal.text", "set", "list");
+
+ // PY-9419
+ public void testConvertParenthesizedTupleToList() {
+ doIntentionTest(CONVERT_TUPLE_TO_LIST);
+ }
+
+ // PY-9419
+ public void testConvertTupleWithoutParenthesesToList() {
+ doIntentionTest(CONVERT_TUPLE_TO_LIST);
+ }
+
+ // PY-9419
+ public void testConvertTupleWithoutClosingParenthesisToList() {
+ doIntentionTest(CONVERT_TUPLE_TO_LIST);
+ }
+
+ // PY-9419
+ public void testConvertParenthesizedTupleToSet() {
+ doIntentionTest(CONVERT_TUPLE_TO_SET);
+ }
+
+ // PY-9419
+ public void testConvertTupleToSetNotAvailableWithoutSetLiterals() {
+ runWithLanguageLevel(LanguageLevel.PYTHON25, new Runnable() {
+ public void run() {
+ doNegativeTest(CONVERT_TUPLE_TO_SET);
+ }
+ });
+ }
+
+ // PY-9419
+ public void testConvertTupleToSetNotAvailableInAssignmentTarget() {
+ doNegativeTest(CONVERT_TUPLE_TO_SET);
+ }
+
+ // PY-9419
+ public void testConvertTupleToSetNotAvailableInForLoop() {
+ doNegativeTest(CONVERT_TUPLE_TO_SET);
+ }
+
+ // PY-9419
+ public void testConvertTupleToSetNotAvailableInComprehension() {
+ doNegativeTest(CONVERT_TUPLE_TO_SET);
+ }
+
+ // PY-9419
+ public void testConvertListToTuple() {
+ doIntentionTest(CONVERT_LIST_TO_TUPLE);
+ }
+
+ // PY-9419
+ public void testConvertListWithoutClosingBracketToTuple() {
+ doIntentionTest(CONVERT_LIST_TO_TUPLE);
+ }
+
+ // PY-9419
+ public void testConvertListToSet() {
+ doIntentionTest(CONVERT_LIST_TO_SET);
+ }
+
+ // PY-9419
+ public void testConvertSetToTuple() {
+ doIntentionTest(CONVERT_SET_TO_TUPLE);
+ }
+
+ // PY-9419
+ public void testConvertSetWithoutClosingBraceToTuple() {
+ doIntentionTest(CONVERT_SET_TO_TUPLE);
+ }
+
+ // PY-9419
+ public void testConvertSetToList() {
+ doIntentionTest(CONVERT_SET_TO_LIST);
+ }
+}