summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniƫl van Noord <13665637+DanielNoord@users.noreply.github.com>2021-11-05 16:54:26 +0100
committerPierre Sassoulas <pierre.sassoulas@gmail.com>2021-11-05 21:26:53 +0100
commit0a1ebd488fcdf7bf306615aba29e401ce49e3e10 (patch)
treeb7d08cf00ff9255e12fa4f1a7571cd9ff53f1676
parent96e84595194073ea54a8c7730b86125049c0f4f9 (diff)
downloadpylint-git-0a1ebd488fcdf7bf306615aba29e401ce49e3e10.tar.gz
Fix crash on checking private members on ``__class__``
Closes #5261
-rw-r--r--ChangeLog4
-rw-r--r--doc/whatsnew/2.12.rst4
-rw-r--r--pylint/checkers/classes.py16
-rw-r--r--tests/functional/u/unused/unused_private_member.py9
4 files changed, 27 insertions, 6 deletions
diff --git a/ChangeLog b/ChangeLog
index 543e397a3..5526acf2e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -140,6 +140,10 @@ Release date: TBA
Closes #5216
+* Fix crash for ``unused-private-member`` when checking private members on ``__class__``
+
+ Closes #5261
+
* Added new checker ``useless-with-lock`` to find incorrect usage of with statement and threading module locks.
Emitted when ``with threading.Lock():`` is used instead of ``with lock_instance:``.
diff --git a/doc/whatsnew/2.12.rst b/doc/whatsnew/2.12.rst
index b2e57a8a7..f3b6bc86c 100644
--- a/doc/whatsnew/2.12.rst
+++ b/doc/whatsnew/2.12.rst
@@ -118,6 +118,10 @@ Other Changes
Closes #3688
+* Fix crash for ``unused-private-member`` when checking private members on ``__class__``
+
+ Closes #5261
+
* Fix double emitting of ``not-callable`` on inferrable ``properties``
Closes #4426
diff --git a/pylint/checkers/classes.py b/pylint/checkers/classes.py
index 730f2e659..82fcc8a61 100644
--- a/pylint/checkers/classes.py
+++ b/pylint/checkers/classes.py
@@ -945,6 +945,7 @@ a metaclass class method.",
)
def _check_unused_private_variables(self, node: nodes.ClassDef) -> None:
+ """Check if private variables are never used within a class"""
for assign_name in node.nodes_of_class(nodes.AssignName):
if isinstance(assign_name.parent, nodes.Arguments):
continue # Ignore function arguments
@@ -953,12 +954,15 @@ a metaclass class method.",
for child in node.nodes_of_class((nodes.Name, nodes.Attribute)):
if isinstance(child, nodes.Name) and child.name == assign_name.name:
break
- if (
- isinstance(child, nodes.Attribute)
- and child.attrname == assign_name.name
- and child.expr.name in ("self", "cls", node.name)
- ):
- break
+ if isinstance(child, nodes.Attribute):
+ if not isinstance(child.expr, nodes.Name):
+ break
+ if child.attrname == assign_name.name and child.expr.name in (
+ "self",
+ "cls",
+ node.name,
+ ):
+ break
else:
args = (node.name, assign_name.name)
self.add_message("unused-private-member", node=assign_name, args=args)
diff --git a/tests/functional/u/unused/unused_private_member.py b/tests/functional/u/unused/unused_private_member.py
index 319a06d88..fc42ea8fb 100644
--- a/tests/functional/u/unused/unused_private_member.py
+++ b/tests/functional/u/unused/unused_private_member.py
@@ -300,3 +300,12 @@ class Pony:
def lookup_attribute(mapping, key):
return mapping[key]
+
+
+# Test for regression on checking __class__ attribute
+# See: https://github.com/PyCQA/pylint/issues/5261
+class Foo:
+ __ham = 1
+
+ def method(self):
+ print(self.__class__.__ham)