diff --git a/python/resources/inspectionDescriptions/PyAssignmentToForLoopParameterInspection.html b/python/resources/inspectionDescriptions/PyAssignmentToForLoopParameterInspection.html
deleted file mode 100644
index 5944aee07d3c..000000000000
--- a/python/resources/inspectionDescriptions/PyAssignmentToForLoopParameterInspection.html
+++ /dev/null
@@ -1,13 +0,0 @@
-
-
-
- This inspection checks for cases when loop variable is redeclared inside of loop.
-
-
- for i in xrange(5):
- for i in xrange(20, 25):
- print("Inner", i)
- print("Outer", i)
-
-
-
diff --git a/python/resources/inspectionDescriptions/PyAssignmentToLoopOrWithParameterInspection.html b/python/resources/inspectionDescriptions/PyAssignmentToLoopOrWithParameterInspection.html
new file mode 100644
index 000000000000..08a234cec60f
--- /dev/null
+++ b/python/resources/inspectionDescriptions/PyAssignmentToLoopOrWithParameterInspection.html
@@ -0,0 +1,21 @@
+
+
+
+ This inspection checks for cases when loop variable is redeclared inside of loop:
+
+
+ for i in xrange(5):
+ for i in xrange(20, 25):
+ print("Inner", i)
+ print("Outer", i)
+
+
+ It also warns you if variable declared in with statement is redeclared inside of statement body:
+
+
+ with open("file") as f:
+ f.read()
+ f = open("another file")
+
+
+
diff --git a/python/src/META-INF/python-core.xml b/python/src/META-INF/python-core.xml
index 424f0f79a19b..742db29c76fd 100644
--- a/python/src/META-INF/python-core.xml
+++ b/python/src/META-INF/python-core.xml
@@ -329,7 +329,7 @@
-
+
diff --git a/python/src/com/jetbrains/python/PyBundle.properties b/python/src/com/jetbrains/python/PyBundle.properties
index f780607189a9..47f4a736797b 100644
--- a/python/src/com/jetbrains/python/PyBundle.properties
+++ b/python/src/com/jetbrains/python/PyBundle.properties
@@ -511,8 +511,8 @@ INSP.none.function.assignment=Function ''{0}'' doesn''t return anything
INSP.NAME.global.undefined=Global variable is undefined at the module level
INSP.NAME.global.$0.undefined=Global variable ''{0}'' is undefined at the module level
-#PyAssignmentToForLoopParameterInspection
-INSP.NAME.assignment.to.for.loop.parameter.display.name=Assignment to 'for' loop parameter
+#PyAssignmentToLoopOrWithParameterInspection
+INSP.NAME.assignment.to.loop.or.with.parameter.display.name=Assignment to 'for' loop or 'with' statement parameter
# Refactoring
# introduce
diff --git a/python/src/com/jetbrains/python/inspections/PyAssignmentToForLoopParameterInspection.java b/python/src/com/jetbrains/python/inspections/PyAssignmentToLoopOrWithParameterInspection.java
similarity index 80%
rename from python/src/com/jetbrains/python/inspections/PyAssignmentToForLoopParameterInspection.java
rename to python/src/com/jetbrains/python/inspections/PyAssignmentToLoopOrWithParameterInspection.java
index fcfb364e338f..1e501a8224b0 100644
--- a/python/src/com/jetbrains/python/inspections/PyAssignmentToForLoopParameterInspection.java
+++ b/python/src/com/jetbrains/python/inspections/PyAssignmentToLoopOrWithParameterInspection.java
@@ -19,10 +19,11 @@ import com.intellij.codeInspection.LocalInspectionToolSession;
import com.intellij.codeInspection.ProblemsHolder;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiElementVisitor;
-import com.intellij.psi.PsiFile;
+import com.intellij.psi.util.PsiTreeUtil;
import com.jetbrains.python.PyBundle;
import com.jetbrains.python.psi.PyForPart;
import com.jetbrains.python.psi.PyTargetExpression;
+import com.jetbrains.python.psi.PyWithStatement;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -34,12 +35,18 @@ import org.jetbrains.annotations.Nullable;
* for i in range(1, 10):
* i = "new value"
*
+ * and
+ *
+ * with open("file") as f:
+ * f.read()
+ * f = open("another file")
+ *
*
* @author link
*/
-public class PyAssignmentToForLoopParameterInspection extends PyInspection {
+public class PyAssignmentToLoopOrWithParameterInspection extends PyInspection {
- private static final String MESSAGE = PyBundle.message("INSP.NAME.assignment.to.for.loop.parameter.display.name");
+ private static final String MESSAGE = PyBundle.message("INSP.NAME.assignment.to.loop.or.with.parameter.display.name");
@NotNull
@Override
@@ -73,14 +80,9 @@ public class PyAssignmentToForLoopParameterInspection extends PyInspection {
return; //We are checking first time declaration
}
- //Find "for" between predecessors until we tree root
- PsiElement element = variableFirstTimeDeclaration;
- while (!(element instanceof PsiFile) && element != null) {
- if (element instanceof PyForPart) {
- registerProblem(node, MESSAGE);
- return;
- }
- element = element.getParent();
+ //Check if variable declared in "for" or "with" statement
+ if (PsiTreeUtil.getNonStrictParentOfType(variableFirstTimeDeclaration, PyForPart.class, PyWithStatement.class) != null) {
+ registerProblem(node, MESSAGE);
}
}
}
diff --git a/python/testData/inspections/PyAssignmentToForLoopParameterInspection/simpleReassignment.py b/python/testData/inspections/PyAssignmentToForLoopParameterInspection/simpleReassignment.py
deleted file mode 100644
index 130176454320..000000000000
--- a/python/testData/inspections/PyAssignmentToForLoopParameterInspection/simpleReassignment.py
+++ /dev/null
@@ -1,3 +0,0 @@
-for i in range(1, 2):
- print(i)
- i = 12
\ No newline at end of file
diff --git a/python/testData/inspections/PyAssignmentToForLoopParameterInspection/tupleAssignment.py b/python/testData/inspections/PyAssignmentToForLoopParameterInspection/tupleAssignment.py
deleted file mode 100644
index 07281c7c9784..000000000000
--- a/python/testData/inspections/PyAssignmentToForLoopParameterInspection/tupleAssignment.py
+++ /dev/null
@@ -1,3 +0,0 @@
-for i in [1, 2, 3]:
- print(i)
- (i, f) = (1, 2)
\ No newline at end of file
diff --git a/python/testData/inspections/PyAssignmentToForLoopParameterInspection/tupleDeclaration.py b/python/testData/inspections/PyAssignmentToForLoopParameterInspection/tupleDeclaration.py
deleted file mode 100644
index 52905d42e134..000000000000
--- a/python/testData/inspections/PyAssignmentToForLoopParameterInspection/tupleDeclaration.py
+++ /dev/null
@@ -1,3 +0,0 @@
-for (k, v) in {"K": "V"}.items():
- print(k)
- k = "12"
\ No newline at end of file
diff --git a/python/testData/inspections/PyAssignmentToForLoopParameterInspection/twoLoops.py b/python/testData/inspections/PyAssignmentToForLoopParameterInspection/twoLoops.py
deleted file mode 100644
index c39f58244512..000000000000
--- a/python/testData/inspections/PyAssignmentToForLoopParameterInspection/twoLoops.py
+++ /dev/null
@@ -1,4 +0,0 @@
-for i in range(5):
- for i in range(20, 25):
- print("Inner", i)
- print("Outer", i)
\ No newline at end of file
diff --git a/python/testData/inspections/PyAssignmentToForLoopParameterInspection/good.py b/python/testData/inspections/PyAssignmentToLoopOrWithParameterInspection/good.py
similarity index 100%
rename from python/testData/inspections/PyAssignmentToForLoopParameterInspection/good.py
rename to python/testData/inspections/PyAssignmentToLoopOrWithParameterInspection/good.py
diff --git a/python/testData/inspections/PyAssignmentToLoopOrWithParameterInspection/simpleReassignment.py b/python/testData/inspections/PyAssignmentToLoopOrWithParameterInspection/simpleReassignment.py
new file mode 100644
index 000000000000..bff004fdc4f5
--- /dev/null
+++ b/python/testData/inspections/PyAssignmentToLoopOrWithParameterInspection/simpleReassignment.py
@@ -0,0 +1,3 @@
+for i in range(1, 2):
+ print(i)
+ i = 12
\ No newline at end of file
diff --git a/python/testData/inspections/PyAssignmentToLoopOrWithParameterInspection/tupleAssignment.py b/python/testData/inspections/PyAssignmentToLoopOrWithParameterInspection/tupleAssignment.py
new file mode 100644
index 000000000000..0606522ae69c
--- /dev/null
+++ b/python/testData/inspections/PyAssignmentToLoopOrWithParameterInspection/tupleAssignment.py
@@ -0,0 +1,3 @@
+for i in [1, 2, 3]:
+ print(i)
+ (i, f) = (1, 2)
\ No newline at end of file
diff --git a/python/testData/inspections/PyAssignmentToLoopOrWithParameterInspection/tupleDeclaration.py b/python/testData/inspections/PyAssignmentToLoopOrWithParameterInspection/tupleDeclaration.py
new file mode 100644
index 000000000000..1469eb81a36d
--- /dev/null
+++ b/python/testData/inspections/PyAssignmentToLoopOrWithParameterInspection/tupleDeclaration.py
@@ -0,0 +1,3 @@
+for (k, v) in {"K": "V"}.items():
+ print(k)
+ k = "12"
\ No newline at end of file
diff --git a/python/testData/inspections/PyAssignmentToLoopOrWithParameterInspection/twoLoops.py b/python/testData/inspections/PyAssignmentToLoopOrWithParameterInspection/twoLoops.py
new file mode 100644
index 000000000000..d26a791db081
--- /dev/null
+++ b/python/testData/inspections/PyAssignmentToLoopOrWithParameterInspection/twoLoops.py
@@ -0,0 +1,4 @@
+for i in range(5):
+ for i in range(20, 25):
+ print("Inner", i)
+ print("Outer", i)
\ No newline at end of file
diff --git a/python/testData/inspections/PyAssignmentToLoopOrWithParameterInspection/withStatement.py b/python/testData/inspections/PyAssignmentToLoopOrWithParameterInspection/withStatement.py
new file mode 100644
index 000000000000..e642026ba896
--- /dev/null
+++ b/python/testData/inspections/PyAssignmentToLoopOrWithParameterInspection/withStatement.py
@@ -0,0 +1,3 @@
+with open("file") as f:
+ f.read()
+ f = open("another file")
\ No newline at end of file
diff --git a/python/testSrc/com/jetbrains/python/inspections/PyAssignmentToForLoopParameterInspectionTest.java b/python/testSrc/com/jetbrains/python/inspections/PyAssignmentToLoopOrWithParameterInspectionTest.java
similarity index 85%
rename from python/testSrc/com/jetbrains/python/inspections/PyAssignmentToForLoopParameterInspectionTest.java
rename to python/testSrc/com/jetbrains/python/inspections/PyAssignmentToLoopOrWithParameterInspectionTest.java
index 9231a3d3a55b..621e2a10fb77 100644
--- a/python/testSrc/com/jetbrains/python/inspections/PyAssignmentToForLoopParameterInspectionTest.java
+++ b/python/testSrc/com/jetbrains/python/inspections/PyAssignmentToLoopOrWithParameterInspectionTest.java
@@ -21,7 +21,7 @@ import org.jetbrains.annotations.NotNull;
/**
* @author link
*/
-public class PyAssignmentToForLoopParameterInspectionTest extends PyInspectionTestCase {
+public class PyAssignmentToLoopOrWithParameterInspectionTest extends PyInspectionTestCase {
public void testGood() {
doTest();
@@ -42,12 +42,15 @@ public class PyAssignmentToForLoopParameterInspectionTest extends PyInspectionTe
public void testTwoLoops() {
doTest();
}
+ public void testWithStatement() {
+ doTest();
+ }
@NotNull
@Override
protected Class extends PyInspection> getInspectionClass() {
- return PyAssignmentToForLoopParameterInspection.class;
+ return PyAssignmentToLoopOrWithParameterInspection.class;
}
@Override