summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorClaudiu Popa <cpopa@cloudbasesolutions.com>2014-10-15 09:25:58 +0300
committerClaudiu Popa <cpopa@cloudbasesolutions.com>2014-10-15 09:25:58 +0300
commit889859a8ac53919ff1c1e85eb0871f6254d96753 (patch)
tree58a1d3ac8a0ab0548a91ba68c2d6c31707175b7c
parente5bdac5711e273a856af6ee2938c3f797501f495 (diff)
downloadpylint-git-889859a8ac53919ff1c1e85eb0871f6254d96753.tar.gz
Add decorated_with_property function to utils.
This is extracted from typechecker, from the property calling detection code.
-rw-r--r--checkers/typecheck.py38
-rw-r--r--checkers/utils.py20
2 files changed, 27 insertions, 31 deletions
diff --git a/checkers/typecheck.py b/checkers/typecheck.py
index 27ed9f527..10b9f8669 100644
--- a/checkers/typecheck.py
+++ b/checkers/typecheck.py
@@ -25,7 +25,9 @@ from astroid.bases import BUILTINS
from pylint.interfaces import IAstroidChecker, INFERENCE, INFERENCE_FAILURE
from pylint.checkers import BaseChecker
-from pylint.checkers.utils import safe_infer, is_super, check_messages
+from pylint.checkers.utils import (
+ safe_infer, is_super,
+ check_messages, decorated_with_property)
MSGS = {
'E1101': ('%s %r has no %r member',
@@ -336,43 +338,17 @@ accessed. Python regular expressions are accepted.'}
except astroid.NotFoundError:
return
- stop_checking = False
for attr in attrs:
if attr is astroid.YES:
continue
- if stop_checking:
- break
if not isinstance(attr, astroid.Function):
continue
# Decorated, see if it is decorated with a property
- if not attr.decorators:
- continue
- for decorator in attr.decorators.nodes:
- if not isinstance(decorator, astroid.Name):
- continue
- try:
- for infered in decorator.infer():
- property_like = False
- if isinstance(infered, astroid.Class):
- if (infered.root().name == BUILTINS and
- infered.name == 'property'):
- property_like = True
- else:
- for ancestor in infered.ancestors():
- if (ancestor.name == 'property' and
- ancestor.root().name == BUILTINS):
- property_like = True
- break
- if property_like:
- self.add_message('not-callable', node=node,
- args=node.func.as_string())
- stop_checking = True
- break
- except InferenceError:
- pass
- if stop_checking:
- break
+ if decorated_with_property(attr):
+ self.add_message('not-callable', node=node,
+ args=node.func.as_string())
+ break
@check_messages(*(list(MSGS.keys())))
def visit_callfunc(self, node):
diff --git a/checkers/utils.py b/checkers/utils.py
index 7aad938b8..4be844c79 100644
--- a/checkers/utils.py
+++ b/checkers/utils.py
@@ -479,3 +479,23 @@ def has_known_bases(klass):
return False
klass._all_bases_known = True
return True
+
+def decorated_with_property(node):
+ """ Detect if the given function node is decorated with a property. """
+ if not node.decorators:
+ return False
+ for decorator in node.decorators.nodes:
+ if not isinstance(decorator, astroid.Name):
+ continue
+ try:
+ for infered in decorator.infer():
+ if isinstance(infered, astroid.Class):
+ if (infered.root().name == BUILTINS_NAME and
+ infered.name == 'property'):
+ return True
+ for ancestor in infered.ancestors():
+ if (ancestor.name == 'property' and
+ ancestor.root().name == BUILTINS_NAME):
+ return True
+ except astroid.InferenceError:
+ pass