Skip to content

Commit

Permalink
[unused-private-member] Handle the case with Call node
Browse files Browse the repository at this point in the history
As seen in issue pylint-dev#4638
  • Loading branch information
Pierre-Sassoulas committed Jun 30, 2021
1 parent 4ea538b commit 57e0d33
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 4 deletions.
4 changes: 4 additions & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@ Release date: TBA
..
Put bug fixes that should not wait for a new minor version here

* Fix a crash that happened when analysing code using ``type(self)`` to access
a class attribute in the ``unused-private-member`` checker.

Closes #4638


What's New in Pylint 2.9.1?
Expand Down
23 changes: 19 additions & 4 deletions pylint/checkers/classes.py
Original file line number Diff line number Diff line change
Expand Up @@ -909,14 +909,29 @@ def _check_unused_private_members(self, node: astroid.ClassDef) -> None:
continue
for attribute in node.nodes_of_class(astroid.Attribute):
attribute = cast(astroid.Attribute, attribute)
if attribute.expr is None: # attribute.expr is probably not really an Optional ?
if attribute.expr is None:
# attribute.expr is an Optional[NodeNG] it can be None
continue
if (
attribute.attrname == function_def.name
and attribute.scope() != function_def # We ignore recursive calls
and attribute.expr.name in ("self", node.name)
attribute.attrname != function_def.name
or attribute.scope() == function_def
):
# We ignore recursive calls
continue
if isinstance(attribute.expr, astroid.Name) and attribute.expr.name in (
"self",
node.name,
):
# self.__attrname / node_name.__attrname
break
if isinstance(attribute.expr, astroid.Call):
# type(self).__attrname
inferred = safe_infer(attribute.expr)
if (
isinstance(inferred, astroid.ClassDef)
and inferred.name == node.name
):
break
else:
function_repr = f"{function_def.name}({function_def.args.as_string()})"
self.add_message(
Expand Down
11 changes: 11 additions & 0 deletions tests/functional/u/unused/unused_private_member.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,3 +66,14 @@ def set_class_var(cls, var):
@classmethod
def get_class_var(cls):
return cls.__class_var


class Bla:
"""Regression test for issue 4638"""

def __init__(self):
type(self).__a()

@classmethod
def __a(cls):
pass

0 comments on commit 57e0d33

Please sign in to comment.