diff options
author | Bryce Guinta <bryce.paul.guinta@gmail.com> | 2018-02-26 23:31:38 -0700 |
---|---|---|
committer | Bryce Guinta <bryce.paul.guinta@gmail.com> | 2018-03-02 22:52:58 -0700 |
commit | c71433d13a7f884cbda48da7b812da42078761fb (patch) | |
tree | 0e45ef954c53c6dad8c8d4a1167327aaa2214a93 | |
parent | 2ad80d92f5e381bda2a7b40e1ee4a81605c7287a (diff) | |
download | pylint-git-c71433d13a7f884cbda48da7b812da42078761fb.tar.gz |
Fix false positive undefined-variable for lambda arguments in classes
Close #1824
-rw-r--r-- | ChangeLog | 5 | ||||
-rw-r--r-- | doc/whatsnew/1.8.rst | 3 | ||||
-rw-r--r-- | pylint/checkers/variables.py | 13 | ||||
-rw-r--r-- | pylint/test/unittest_checker_variables.py | 13 |
4 files changed, 32 insertions, 2 deletions
@@ -22,6 +22,11 @@ Release date: - Close #1794 (second part) + * Fix false positive undefined-variable for lambda argument in + class definitions + + Close #1824 + What's New in Pylint 1.8.2? ========================== diff --git a/doc/whatsnew/1.8.rst b/doc/whatsnew/1.8.rst index 422aa70f6..7cf3b354b 100644 --- a/doc/whatsnew/1.8.rst +++ b/doc/whatsnew/1.8.rst @@ -385,3 +385,6 @@ Other Changes * Fix false positive ``inconsistent-return-statements`` message by avoiding useless exception inference if the exception is not handled. (backport from 2.0) + +* Fix false positive ``undefined-variable`` for lambda arguments in + class definitions diff --git a/pylint/checkers/variables.py b/pylint/checkers/variables.py index 9d856c3b3..4af7f53bb 100644 --- a/pylint/checkers/variables.py +++ b/pylint/checkers/variables.py @@ -961,6 +961,10 @@ class VariablesChecker(BaseChecker): def _is_variable_violation(node, name, defnode, stmt, defstmt, frame, defframe, base_scope_type, recursive_klass): + # node: Node to check for violation + # name: name of node to check violation for + # frame: Scope of statement of node + # base_scope_type: local scope type maybee0601 = True annotation_return = False use_outer_definition = False @@ -974,8 +978,13 @@ class VariablesChecker(BaseChecker): else: # we are in a local scope, check the name is not # defined in global or builtin scope - # skip this lookup if name is assigned later in function scope - forbid_lookup = isinstance(frame, astroid.FunctionDef) and _assigned_locally(node) + # skip this lookup if name is assigned later in function scope/lambda + # Note: the node.frame() is not the same as the `frame` argument which is + # equivalent to frame.statement().scope() + forbid_lookup = ((isinstance(frame, astroid.FunctionDef) or + isinstance(node.frame(), astroid.Lambda)) and + _assigned_locally(node)) + if not forbid_lookup and defframe.root().lookup(name)[1]: maybee0601 = False use_outer_definition = ( diff --git a/pylint/test/unittest_checker_variables.py b/pylint/test/unittest_checker_variables.py index 23142ba38..1ef4a50d2 100644 --- a/pylint/test/unittest_checker_variables.py +++ b/pylint/test/unittest_checker_variables.py @@ -165,6 +165,19 @@ class TestVariablesCheckerWithTearDown(CheckerTestCase): with self.assertNoMessages(): self.walk(node) + def test_lambda_in_classdef(self): + # Make sure lambda doesn't raises + # Undefined-method in class function + + # Issue 1824 + # https://github.com/PyCQA/pylint/issues/1824 + node = astroid.parse(''' + class MyObject(object): + method1 = lambda func: func() + method2 = lambda function: function() + ''') + with self.assertNoMessages(): + self.walk(node) class TestMissingSubmodule(CheckerTestCase): CHECKER_CLASS = variables.VariablesChecker |