diff options
author | cpopa <devnull@localhost> | 2014-09-18 16:54:11 +0300 |
---|---|---|
committer | cpopa <devnull@localhost> | 2014-09-18 16:54:11 +0300 |
commit | f01bff14710891ad28f351c608aa6a316eeb2372 (patch) | |
tree | cd36cf68084fc036b6f75f784a26cd78b98f053d | |
parent | 0850110102941286ff838e1c8b18530c4fd17bc3 (diff) | |
download | pylint-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-- | ChangeLog | 4 | ||||
-rw-r--r-- | checkers/variables.py | 21 | ||||
-rw-r--r-- | test/functional/undefined_variable_py30.py | 21 | ||||
-rw-r--r-- | test/functional/undefined_variable_py30.txt | 5 |
4 files changed, 48 insertions, 3 deletions
@@ -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 |