diff options
author | Claudiu Popa <cpopa@cloudbasesolutions.com> | 2014-10-15 09:25:58 +0300 |
---|---|---|
committer | Claudiu Popa <cpopa@cloudbasesolutions.com> | 2014-10-15 09:25:58 +0300 |
commit | 889859a8ac53919ff1c1e85eb0871f6254d96753 (patch) | |
tree | 58a1d3ac8a0ab0548a91ba68c2d6c31707175b7c | |
parent | e5bdac5711e273a856af6ee2938c3f797501f495 (diff) | |
download | pylint-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.py | 38 | ||||
-rw-r--r-- | checkers/utils.py | 20 |
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 |