summaryrefslogtreecommitdiff
path: root/pylint/checkers/classes.py
diff options
context:
space:
mode:
authorClaudiu Popa <pcmanticore@gmail.com>2019-03-03 13:27:37 +0100
committerClaudiu Popa <pcmanticore@gmail.com>2019-03-03 13:27:37 +0100
commit097227b612d3bac2bed5528b72ccea4309ff5c32 (patch)
tree83e50eeb12e406d72c6718f9cdba5dcf2f56679c /pylint/checkers/classes.py
parent73c5c2fd4d5de0d38bebed7bd3688cb747225f39 (diff)
downloadpylint-git-097227b612d3bac2bed5528b72ccea4309ff5c32.tar.gz
Added a new check `class-variable-slots-conflict`
This check is emitted when ``pylint`` finds a class variable that conflicts with a slot name, which would raise a ``ValueError`` at runtime.
Diffstat (limited to 'pylint/checkers/classes.py')
-rw-r--r--pylint/checkers/classes.py31
1 files changed, 21 insertions, 10 deletions
diff --git a/pylint/checkers/classes.py b/pylint/checkers/classes.py
index 2fb152bd1..de255fe6a 100644
--- a/pylint/checkers/classes.py
+++ b/pylint/checkers/classes.py
@@ -596,6 +596,11 @@ MSGS = {
"duplicate-bases",
"Used when a class has duplicate bases.",
),
+ "E0242": (
+ "Value %r in slots conflicts with class variable",
+ "class-variable-slots-conflict",
+ "Used when a value in __slots__ conflicts with a class variable, property or method.",
+ ),
"R0202": (
"Consider using a decorator instead of calling classmethod",
"no-classmethod-decorator",
@@ -1050,27 +1055,33 @@ a metaclass class method.",
values = slots.itered()
if values is astroid.Uninferable:
return
-
for elt in values:
try:
- self._check_slots_elt(elt)
+ self._check_slots_elt(elt, node)
except astroid.InferenceError:
continue
- def _check_slots_elt(self, elt):
- for infered in elt.infer():
- if infered is astroid.Uninferable:
+ def _check_slots_elt(self, elt, node):
+ for inferred in elt.infer():
+ if inferred is astroid.Uninferable:
continue
- if not isinstance(infered, astroid.Const) or not isinstance(
- infered.value, str
+ if not isinstance(inferred, astroid.Const) or not isinstance(
+ inferred.value, str
):
self.add_message(
- "invalid-slots-object", args=infered.as_string(), node=elt
+ "invalid-slots-object", args=inferred.as_string(), node=elt
)
continue
- if not infered.value:
+ if not inferred.value:
+ self.add_message(
+ "invalid-slots-object", args=inferred.as_string(), node=elt
+ )
+
+ # Check if we have a conflict with a class variable
+ class_variable = node.locals.get(inferred.value)
+ if class_variable:
self.add_message(
- "invalid-slots-object", args=infered.as_string(), node=elt
+ "class-variable-slots-conflict", args=(inferred.value,), node=elt
)
def leave_functiondef(self, node):