summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcpopa <devnull@localhost>2014-09-18 16:54:11 +0300
committercpopa <devnull@localhost>2014-09-18 16:54:11 +0300
commitf01bff14710891ad28f351c608aa6a316eeb2372 (patch)
treecd36cf68084fc036b6f75f784a26cd78b98f053d
parent0850110102941286ff838e1c8b18530c4fd17bc3 (diff)
downloadpylint-f01bff14710891ad28f351c608aa6a316eeb2372.tar.gz
Fix another false positives with 'undefined-variable', where the variable can be found as a class assignment and used in a function annotation. Closes issue #342.
-rw-r--r--ChangeLog4
-rw-r--r--checkers/variables.py21
-rw-r--r--test/functional/undefined_variable_py30.py21
-rw-r--r--test/functional/undefined_variable_py30.txt5
4 files changed, 48 insertions, 3 deletions
diff --git a/ChangeLog b/ChangeLog
index 3147542..15a1c1a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -110,6 +110,10 @@ ChangeLog for Pylint
* Add a new warning, 'inherit-non-class', emitted when a class inherits
from something which is not a class. Closes issue #331.
+ * Fix another false positives with 'undefined-variable', where the variable
+ can be found as a class assignment and used in a function annotation.
+ Closes issue #342.
+
2014-07-26 -- 1.3.0
diff --git a/checkers/variables.py b/checkers/variables.py
index 8bd05b3..d1b04e1 100644
--- a/checkers/variables.py
+++ b/checkers/variables.py
@@ -737,11 +737,28 @@ builtins. Remember that you should avoid to define new builtins when possible.'
base_scope_type == 'comprehension' and i == start_index-1):
# Detect if we are in a local class scope, as an assignment.
# For example, the following is fair game.
+ #
# class A:
# b = 1
# c = lambda b=b: b * b
- if not (isinstance(frame, astroid.Class) and
- name in frame.locals):
+ #
+ # class B:
+ # tp = 1
+ # def func(self, arg: tp):
+ # ...
+
+ in_annotation = (
+ PY3K and isinstance(frame, astroid.Function)
+ and node.statement() is frame and
+ (node in frame.args.annotations
+ or node is frame.args.varargannotation
+ or node is frame.args.kwargannotation))
+ if in_annotation:
+ frame_locals = frame.parent.scope().locals
+ else:
+ frame_locals = frame.locals
+ if not ((isinstance(frame, astroid.Class) or in_annotation)
+ and name in frame_locals):
continue
# the name has already been consumed, only check it's not a loop
# variable used outside the loop
diff --git a/test/functional/undefined_variable_py30.py b/test/functional/undefined_variable_py30.py
index 74e65a6..40cbdcc 100644
--- a/test/functional/undefined_variable_py30.py
+++ b/test/functional/undefined_variable_py30.py
@@ -35,3 +35,24 @@ class Undefined1:
def test1(self)->ABC: # [undefined-variable]
""" Triggers undefined-variable. """
+
+
+class FalsePositive342(object):
+ # pylint: disable=line-too-long
+ """ Fix some false positives found in
+ https://bitbucket.org/logilab/pylint/issue/342/spurious-undefined-variable-for-class
+ """
+
+ top = 42
+
+ def test_good(self, abc: top):
+ """ top is defined at this moment. """
+
+ def test_bad(self, abc: trop): # [undefined-variable]
+ """ trop is undefined at this moment. """
+
+ def test_bad1(self, *args: trop1): # [undefined-variable]
+ """ trop1 is undefined at this moment. """
+
+ def test_bad2(self, **abc: trop2): # [undefined-variable]
+ """ trop2 is undefined at this moment. """
diff --git a/test/functional/undefined_variable_py30.txt b/test/functional/undefined_variable_py30.txt
index 30004bd..f6a7596 100644
--- a/test/functional/undefined_variable_py30.txt
+++ b/test/functional/undefined_variable_py30.txt
@@ -1,3 +1,6 @@
undefined-variable:8:Undefined.test:Undefined variable 'Undefined'
undefined-variable:33:Undefined1.InnerScope.test_undefined:Undefined variable 'Undef'
-undefined-variable:36:Undefined1.InnerScope.test1:Undefined variable 'ABC' \ No newline at end of file
+undefined-variable:36:Undefined1.InnerScope.test1:Undefined variable 'ABC'
+undefined-variable:51:FalsePositive342.test_bad:Undefined variable 'trop'
+undefined-variable:54:FalsePositive342.test_bad1:Undefined variable 'trop1'
+undefined-variable:57:FalsePositive342.test_bad2:Undefined variable 'trop2' \ No newline at end of file