summaryrefslogtreecommitdiff
path: root/pylint/checkers/variables.py
diff options
context:
space:
mode:
Diffstat (limited to 'pylint/checkers/variables.py')
-rw-r--r--pylint/checkers/variables.py42
1 files changed, 35 insertions, 7 deletions
diff --git a/pylint/checkers/variables.py b/pylint/checkers/variables.py
index 390bb5931..62fadd2fd 100644
--- a/pylint/checkers/variables.py
+++ b/pylint/checkers/variables.py
@@ -973,13 +973,11 @@ class VariablesChecker(BaseChecker):
# if the current scope is a class scope but it's not the inner
# scope, ignore it. This prevents to access this scope instead of
# the globals one in function members when there are some common
- # names. The only exception is when the starting scope is a
- # comprehension and its direct outer scope is a class
- if (
- current_consumer.scope_type == "class"
- and i != start_index
- and not (base_scope_type == "comprehension" and i == start_index - 1)
- ):
+ # names.
+ if current_consumer.scope_type == "class" and i != start_index:
+ # The only exceptions are: when the variable forms an iter within a
+ # comprehension scope; and/or when used as a default, decorator,
+ # or annotation within a function.
if self._ignore_class_scope(node):
continue
@@ -1269,6 +1267,35 @@ class VariablesChecker(BaseChecker):
return in_annotation_or_default_or_decorator
@staticmethod
+ def _in_lambda_or_comprehension_body(
+ node: astroid.node_classes.NodeNG, frame: astroid.node_classes.NodeNG
+ ) -> bool:
+ """return True if node within a lambda/comprehension body (or similar) and thus should not have access to class attributes in frame"""
+ child = node
+ parent = node.parent
+ while parent is not None:
+ if parent is frame:
+ return False
+ if isinstance(parent, astroid.Lambda) and not child is parent.args:
+ # Body of lambda should not have access to class attributes.
+ return True
+ if (
+ isinstance(parent, astroid.node_classes.Comprehension)
+ and not child is parent.iter
+ ):
+ # Only iter of list/set/dict/generator comprehension should have access.
+ return True
+ if isinstance(parent, astroid.scoped_nodes.ComprehensionScope) and not (
+ parent.generators and child is parent.generators[0]
+ ):
+ # Body of list/set/dict/generator comprehension should not have access to class attributes.
+ # Furthermore, only the first generator (if multiple) in comprehension should have access.
+ return True
+ child = parent
+ parent = parent.parent
+ return False
+
+ @staticmethod
def _is_variable_violation(
node,
name,
@@ -1439,6 +1466,7 @@ class VariablesChecker(BaseChecker):
isinstance(frame, astroid.ClassDef)
or in_annotation_or_default_or_decorator
)
+ and not self._in_lambda_or_comprehension_body(node, frame)
and name in frame_locals
)