From d7281a83a963b0776e42f7d2b2129e0af6fb9cfc Mon Sep 17 00:00:00 2001 From: Ekaterina Tuzova Date: Fri, 22 Mar 2013 15:29:35 +0400 Subject: [PATCH] implemented pylint W0601 Inspection is used when a variable is defined through the "global" statement but the variable is not defined in the module scope. --- python/src/META-INF/python-plugin-common.xml | 1 + .../com/jetbrains/python/PyBundle.properties | 8 ++- .../PyGlobalUndefinedInspection.java | 51 +++++++++++++++++++ .../PyClassHasNoInitInspection/parentClass.py | 2 +- .../trueNegative.py | 8 +++ .../truePositive.py | 6 +++ .../noReturn.py | 2 +- .../pass.py | 2 +- .../returnNone.py | 2 +- .../PyGlobalUndefinedInspectionTest.java | 23 +++++++++ 10 files changed, 99 insertions(+), 6 deletions(-) create mode 100644 python/src/com/jetbrains/python/inspections/PyGlobalUndefinedInspection.java create mode 100644 python/testData/inspections/PyGlobalUndefinedInspection/trueNegative.py create mode 100644 python/testData/inspections/PyGlobalUndefinedInspection/truePositive.py create mode 100644 python/testSrc/com/jetbrains/python/inspections/PyGlobalUndefinedInspectionTest.java diff --git a/python/src/META-INF/python-plugin-common.xml b/python/src/META-INF/python-plugin-common.xml index bb7888c51277..2eb8d1ce0151 100644 --- a/python/src/META-INF/python-plugin-common.xml +++ b/python/src/META-INF/python-plugin-common.xml @@ -319,6 +319,7 @@ + diff --git a/python/src/com/jetbrains/python/PyBundle.properties b/python/src/com/jetbrains/python/PyBundle.properties index a888fe16383c..c224e40e0673 100644 --- a/python/src/com/jetbrains/python/PyBundle.properties +++ b/python/src/com/jetbrains/python/PyBundle.properties @@ -474,11 +474,15 @@ INSP.NAME.requirements=Package requirements # PyClassHasNoInitInspection INSP.NAME.class.has.no.init=Class has no __init__ method INSP.class.has.no.init=Class has no __init__ method -INSP.parent.$0.has.no.init=Parent {0} has no __init__ method +INSP.parent.$0.has.no.init=Parent ''{0}'' has no __init__ method #PyNoneFunctionAssignmentInspection INSP.NAME.none.function.assignment=Assigning function call that doesn't return anything (None) -INSP.none.function.assignment=Function {0} doesn''t return anything +INSP.none.function.assignment=Function ''{0}'' doesn''t return anything + +#PyGlobalUndefinedInspection +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 # Refactoring # introduce diff --git a/python/src/com/jetbrains/python/inspections/PyGlobalUndefinedInspection.java b/python/src/com/jetbrains/python/inspections/PyGlobalUndefinedInspection.java new file mode 100644 index 000000000000..132c55ddf7a7 --- /dev/null +++ b/python/src/com/jetbrains/python/inspections/PyGlobalUndefinedInspection.java @@ -0,0 +1,51 @@ +package com.jetbrains.python.inspections; + +import com.intellij.codeInspection.LocalInspectionToolSession; +import com.intellij.codeInspection.ProblemsHolder; +import com.intellij.psi.PsiElementVisitor; +import com.jetbrains.python.PyBundle; +import com.jetbrains.python.psi.PyGlobalStatement; +import com.jetbrains.python.psi.PyTargetExpression; +import org.jetbrains.annotations.Nls; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +/** + * User: ktisha + * + * pylint W0601 + */ +public class PyGlobalUndefinedInspection extends PyInspection { + @Nls + @NotNull + @Override + public String getDisplayName() { + return PyBundle.message("INSP.NAME.global.undefined"); + } + + @NotNull + @Override + public PsiElementVisitor buildVisitor(@NotNull ProblemsHolder holder, + boolean isOnTheFly, + @NotNull LocalInspectionToolSession session) { + return new Visitor(holder, session); + } + + + private static class Visitor extends PyInspectionVisitor { + public Visitor(@Nullable ProblemsHolder holder, @NotNull LocalInspectionToolSession session) { + super(holder, session); + } + + @Override + public void visitPyGlobalStatement(PyGlobalStatement node) { + final PyTargetExpression[] globals = node.getGlobals(); + + for (PyTargetExpression global : globals) { + if (global.getReference().resolve() == global) { + registerProblem(global, PyBundle.message("INSP.NAME.global.$0.undefined", global.getName())); + } + } + } + } +} diff --git a/python/testData/inspections/PyClassHasNoInitInspection/parentClass.py b/python/testData/inspections/PyClassHasNoInitInspection/parentClass.py index 88e0fa2058d3..b28f8965302b 100644 --- a/python/testData/inspections/PyClassHasNoInitInspection/parentClass.py +++ b/python/testData/inspections/PyClassHasNoInitInspection/parentClass.py @@ -3,7 +3,7 @@ class A: def foo(self): self.b = 1 -class B(A): +class B(A): def __init__(self): self.b = 2 diff --git a/python/testData/inspections/PyGlobalUndefinedInspection/trueNegative.py b/python/testData/inspections/PyGlobalUndefinedInspection/trueNegative.py new file mode 100644 index 000000000000..928d6c65d41b --- /dev/null +++ b/python/testData/inspections/PyGlobalUndefinedInspection/trueNegative.py @@ -0,0 +1,8 @@ +__author__ = 'ktisha' +bar = 1 + +def foo(): + global bar + print bar + +foo() \ No newline at end of file diff --git a/python/testData/inspections/PyGlobalUndefinedInspection/truePositive.py b/python/testData/inspections/PyGlobalUndefinedInspection/truePositive.py new file mode 100644 index 000000000000..d34a29765a7d --- /dev/null +++ b/python/testData/inspections/PyGlobalUndefinedInspection/truePositive.py @@ -0,0 +1,6 @@ +__author__ = 'ktisha' +def foo(): + global bar + print bar + +foo() \ No newline at end of file diff --git a/python/testData/inspections/PyNoneFunctionAssignmentInspection/noReturn.py b/python/testData/inspections/PyNoneFunctionAssignmentInspection/noReturn.py index fd8857107147..7b14161bb1fc 100644 --- a/python/testData/inspections/PyNoneFunctionAssignmentInspection/noReturn.py +++ b/python/testData/inspections/PyNoneFunctionAssignmentInspection/noReturn.py @@ -3,4 +3,4 @@ __author__ = 'ktisha' def foo(): a = 1 -b = foo() \ No newline at end of file +b = foo() \ No newline at end of file diff --git a/python/testData/inspections/PyNoneFunctionAssignmentInspection/pass.py b/python/testData/inspections/PyNoneFunctionAssignmentInspection/pass.py index 3f099ddc98f1..6caff7dada73 100644 --- a/python/testData/inspections/PyNoneFunctionAssignmentInspection/pass.py +++ b/python/testData/inspections/PyNoneFunctionAssignmentInspection/pass.py @@ -3,4 +3,4 @@ __author__ = 'ktisha' def foo(): pass -b = foo() \ No newline at end of file +b = foo() \ No newline at end of file diff --git a/python/testData/inspections/PyNoneFunctionAssignmentInspection/returnNone.py b/python/testData/inspections/PyNoneFunctionAssignmentInspection/returnNone.py index c1d5ad50a263..c92aadde89b7 100644 --- a/python/testData/inspections/PyNoneFunctionAssignmentInspection/returnNone.py +++ b/python/testData/inspections/PyNoneFunctionAssignmentInspection/returnNone.py @@ -3,4 +3,4 @@ __author__ = 'ktisha' def foo(): return None -b = foo() \ No newline at end of file +b = foo() \ No newline at end of file diff --git a/python/testSrc/com/jetbrains/python/inspections/PyGlobalUndefinedInspectionTest.java b/python/testSrc/com/jetbrains/python/inspections/PyGlobalUndefinedInspectionTest.java new file mode 100644 index 000000000000..cad5cd00286b --- /dev/null +++ b/python/testSrc/com/jetbrains/python/inspections/PyGlobalUndefinedInspectionTest.java @@ -0,0 +1,23 @@ +package com.jetbrains.python.inspections; + +import com.jetbrains.python.fixtures.PyTestCase; + +/** + * User: ktisha + */ +public class PyGlobalUndefinedInspectionTest extends PyTestCase { + + public void testTruePositive() { + doTest(); + } + + public void testTrueNegative() { + doTest(); + } + + private void doTest() { + myFixture.configureByFile("inspections/PyGlobalUndefinedInspection/" + getTestName(true) + ".py"); + myFixture.enableInspections(PyGlobalUndefinedInspection.class); + myFixture.checkHighlighting(false, false, true); + } +}