summaryrefslogtreecommitdiff
path: root/pylint/checkers
diff options
context:
space:
mode:
authorClaudiu Popa <pcmanticore@gmail.com>2015-10-04 22:16:22 +0300
committerClaudiu Popa <pcmanticore@gmail.com>2015-10-04 22:16:22 +0300
commit20b663ec6fb7cf830559e169e5fb106f9bd182ac (patch)
tree7850bff6e62413cd4be89c92679dcad3a19b8767 /pylint/checkers
parent48f89e053b0b91d5cc1a1401a5b871815e4bcf9e (diff)
downloadpylint-20b663ec6fb7cf830559e169e5fb106f9bd182ac.tar.gz
Don't emit 'assigning-non-slot' for descriptors. Closes issue #652.
Diffstat (limited to 'pylint/checkers')
-rw-r--r--pylint/checkers/classes.py23
1 files changed, 23 insertions, 0 deletions
diff --git a/pylint/checkers/classes.py b/pylint/checkers/classes.py
index 71041ea..0fc0fae 100644
--- a/pylint/checkers/classes.py
+++ b/pylint/checkers/classes.py
@@ -57,6 +57,25 @@ def _is_invalid_base_class(cls):
return cls.name in INVALID_BASE_CLASSES and is_builtin_object(cls)
+def _has_data_descriptor(cls, attr):
+ attributes = cls.getattr(attr)
+ for attribute in attributes:
+ try:
+ for inferred in attribute.infer():
+ if isinstance(inferred, astroid.Instance):
+ try:
+ inferred.getattr('__get__')
+ inferred.getattr('__set__')
+ except astroid.NotFoundError:
+ continue
+ else:
+ return True
+ except astroid.InferenceError:
+ # Can't infer, avoid emitting a false positive in this case.
+ return True
+ return False
+
+
def _called_in_methods(func, klass, methods):
""" Check if the func was called in any of the given methods,
belonging to the *klass*. Returns True if so, False otherwise.
@@ -578,6 +597,10 @@ a metaclass class method.'}
# Properties circumvent the slots mechanism,
# so we should not emit a warning for them.
return
+ if (node.attrname in klass.locals
+ and _has_data_descriptor(klass, node.attrname)):
+ # Descriptors circumvent the slots mechanism as well.
+ return
self.add_message('assigning-non-slot',
args=(node.attrname, ), node=node)