diff --git a/python/psi-api/src/com/jetbrains/python/psi/PyStarExpression.java b/python/psi-api/src/com/jetbrains/python/psi/PyStarExpression.java
index 1702efcc50b0..54eb30daaa2c 100644
--- a/python/psi-api/src/com/jetbrains/python/psi/PyStarExpression.java
+++ b/python/psi-api/src/com/jetbrains/python/psi/PyStarExpression.java
@@ -23,4 +23,6 @@ import org.jetbrains.annotations.Nullable;
public interface PyStarExpression extends PyExpression {
@Nullable
PyExpression getExpression();
+ boolean isAssignmentTarget();
+ boolean isUnpacking();
}
diff --git a/python/src/com/jetbrains/python/psi/impl/PyStarExpressionImpl.java b/python/src/com/jetbrains/python/psi/impl/PyStarExpressionImpl.java
index 2dc478528e48..64fb8aa8c452 100644
--- a/python/src/com/jetbrains/python/psi/impl/PyStarExpressionImpl.java
+++ b/python/src/com/jetbrains/python/psi/impl/PyStarExpressionImpl.java
@@ -16,10 +16,9 @@
package com.jetbrains.python.psi.impl;
import com.intellij.lang.ASTNode;
+import com.intellij.psi.PsiElement;
import com.intellij.psi.util.PsiTreeUtil;
-import com.jetbrains.python.psi.PyElementVisitor;
-import com.jetbrains.python.psi.PyExpression;
-import com.jetbrains.python.psi.PyStarExpression;
+import com.jetbrains.python.psi.*;
import com.jetbrains.python.psi.types.PyType;
import com.jetbrains.python.psi.types.TypeEvalContext;
import org.jetbrains.annotations.NotNull;
@@ -48,4 +47,19 @@ public class PyStarExpressionImpl extends PyElementImpl implements PyStarExpress
public void acceptPyVisitor(PyElementVisitor visitor) {
visitor.visitPyStarExpression(this);
}
+
+ public boolean isAssignmentTarget() {
+ return getExpression() instanceof PyTargetExpression;
+ }
+
+ public boolean isUnpacking() {
+ if (isAssignmentTarget()) {
+ return false;
+ }
+ PsiElement parent = getParent();
+ while (parent instanceof PyParenthesizedExpression) {
+ parent = parent.getParent();
+ }
+ return parent instanceof PyTupleExpression || parent instanceof PyListLiteralExpression;
+ }
}
diff --git a/python/src/com/jetbrains/python/validation/CompatibilityVisitor.java b/python/src/com/jetbrains/python/validation/CompatibilityVisitor.java
index ddc12854d316..4a54685dc4fa 100644
--- a/python/src/com/jetbrains/python/validation/CompatibilityVisitor.java
+++ b/python/src/com/jetbrains/python/validation/CompatibilityVisitor.java
@@ -170,16 +170,32 @@ public abstract class CompatibilityVisitor extends PyAnnotator {
@Override
public void visitPyStarExpression(PyStarExpression node) {
super.visitPyStarExpression(node);
- int len = 0;
- StringBuilder message = new StringBuilder(myCommonMessage);
- for (int i = 0; i != myVersionsToProcess.size(); ++i) {
- LanguageLevel languageLevel = myVersionsToProcess.get(i);
- if (!languageLevel.isPy3K()) {
- len = appendLanguageLevel(message, len, languageLevel);
+
+ if (node.isAssignmentTarget()) {
+ boolean problem = false;
+ for (LanguageLevel level : myVersionsToProcess) {
+ if (level.isOlderThan(LanguageLevel.PYTHON30)) {
+ problem = true;
+ break;
+ }
+ }
+ if (problem) {
+ registerProblem(node, "Python versions < 3.0 do not support starred expressions as assignment targets");
+ }
+ }
+
+ if (node.isUnpacking()) {
+ boolean problem = false;
+ for (LanguageLevel level : myVersionsToProcess) {
+ if (level.isOlderThan(LanguageLevel.PYTHON35)) {
+ problem = true;
+ break;
+ }
+ }
+ if (problem) {
+ registerProblem(node, "Python version < 3.5 do not support starred expressions in tuples, lists, and sets");
}
}
- commonRegisterProblem(message, " not support this syntax. Starred expressions are not allowed as assignment targets in Python 2",
- len, node, null);
}
@Override
diff --git a/python/src/com/jetbrains/python/validation/StarAnnotator.java b/python/src/com/jetbrains/python/validation/StarAnnotator.java
index 0b6dd5372737..1a0e01b415e1 100644
--- a/python/src/com/jetbrains/python/validation/StarAnnotator.java
+++ b/python/src/com/jetbrains/python/validation/StarAnnotator.java
@@ -15,9 +15,7 @@
*/
package com.jetbrains.python.validation;
-import com.intellij.psi.PsiElement;
-import com.jetbrains.python.psi.*;
-import org.jetbrains.annotations.NotNull;
+import com.jetbrains.python.psi.PyStarExpression;
/**
* @author yole
@@ -26,20 +24,8 @@ public class StarAnnotator extends PyAnnotator {
@Override
public void visitPyStarExpression(PyStarExpression node) {
super.visitPyStarExpression(node);
- if (!isAssignmentTarget(node) && !isStarUnpacking(node)) {
+ if (!node.isAssignmentTarget() && !node.isUnpacking()) {
getHolder().createErrorAnnotation(node, "Can't use starred expression here");
}
}
-
- private static boolean isStarUnpacking(@NotNull PyStarExpression node) {
- PsiElement parent = node.getParent();
- while (parent instanceof PyParenthesizedExpression) {
- parent = parent.getParent();
- }
- return parent instanceof PyTupleExpression || parent instanceof PyListLiteralExpression;
- }
-
- private static boolean isAssignmentTarget(@NotNull PyStarExpression node) {
- return node.getExpression() instanceof PyTargetExpression;
- }
}
diff --git a/python/testData/inspections/PyCompatibilityInspection/starExpression.py b/python/testData/inspections/PyCompatibilityInspection/starExpression.py
index 19333a1ab8cb..1858b6269208 100644
--- a/python/testData/inspections/PyCompatibilityInspection/starExpression.py
+++ b/python/testData/inspections/PyCompatibilityInspection/starExpression.py
@@ -1,2 +1,2 @@
-t = (1, 2, 3)
-a, *b, c = t
\ No newline at end of file
+t = (1, *(2, 3))
+a, *b, c = t
diff --git a/python/testData/inspections/PyUnusedVariableTupleUnpacking/test.py b/python/testData/inspections/PyUnusedVariableTupleUnpacking/test.py
index 70a64d22ef03..1e504dff73bb 100644
--- a/python/testData/inspections/PyUnusedVariableTupleUnpacking/test.py
+++ b/python/testData/inspections/PyUnusedVariableTupleUnpacking/test.py
@@ -3,8 +3,8 @@ def foo():
print x
def test_vlu():
- *h, t = [1, 2, 3] # fail
+ *h, t = [1, 2, 3] # fail
def test_vlu():
- *h, t = [1, 2, 3] # pass
+ *h, t = [1, 2, 3] # pass
print(t)
\ No newline at end of file
diff --git a/python/testSrc/com/jetbrains/python/inspections/PyCompatibilityInspectionTest.java b/python/testSrc/com/jetbrains/python/inspections/PyCompatibilityInspectionTest.java
index 49e9acb6929f..f1617e8be29c 100644
--- a/python/testSrc/com/jetbrains/python/inspections/PyCompatibilityInspectionTest.java
+++ b/python/testSrc/com/jetbrains/python/inspections/PyCompatibilityInspectionTest.java
@@ -55,7 +55,7 @@ public class PyCompatibilityInspectionTest extends PyTestCase {
}
public void testStarExpression() {
- setLanguageLevel(LanguageLevel.PYTHON30);
+ setLanguageLevel(LanguageLevel.PYTHON35);
doTest();
}