summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBryce Guinta <bryce.paul.guinta@gmail.com>2018-02-26 23:31:38 -0700
committerBryce Guinta <bryce.paul.guinta@gmail.com>2018-03-02 22:52:58 -0700
commitc71433d13a7f884cbda48da7b812da42078761fb (patch)
tree0e45ef954c53c6dad8c8d4a1167327aaa2214a93
parent2ad80d92f5e381bda2a7b40e1ee4a81605c7287a (diff)
downloadpylint-git-c71433d13a7f884cbda48da7b812da42078761fb.tar.gz
Fix false positive undefined-variable for lambda arguments in classes
Close #1824
-rw-r--r--ChangeLog5
-rw-r--r--doc/whatsnew/1.8.rst3
-rw-r--r--pylint/checkers/variables.py13
-rw-r--r--pylint/test/unittest_checker_variables.py13
4 files changed, 32 insertions, 2 deletions
diff --git a/ChangeLog b/ChangeLog
index 4e915a9d4..aa08a92f6 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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