diff options
-rw-r--r-- | ChangeLog | 5 | ||||
-rw-r--r-- | doc/whatsnew/2.0.rst | 3 | ||||
-rw-r--r-- | pylint/checkers/variables.py | 12 | ||||
-rw-r--r-- | pylint/test/unittest_checker_variables.py | 13 |
4 files changed, 31 insertions, 2 deletions
@@ -87,6 +87,11 @@ What's New in Pylint 2.0? Close #1120 + * Fix false positive undefined-variable for lambda argument in + class definitions + + Close #1824 + What's New in Pylint 1.8.1? ========================= diff --git a/doc/whatsnew/2.0.rst b/doc/whatsnew/2.0.rst index 783719ab6..c9060d3b1 100644 --- a/doc/whatsnew/2.0.rst +++ b/doc/whatsnew/2.0.rst @@ -38,3 +38,6 @@ Other Changes * Fix false positive ``inconsistent-return-statements`` message by avoiding useless exception inference if the exception is not handled. + +* Fix false positive ``undefined-variable`` for lambda argument in + class definitions diff --git a/pylint/checkers/variables.py b/pylint/checkers/variables.py index f8519507d..fd01b3072 100644 --- a/pylint/checkers/variables.py +++ b/pylint/checkers/variables.py @@ -956,6 +956,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 @@ -969,8 +973,12 @@ 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..4afcd22c9 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 def + + # 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 |