diff options
author | Claudiu Popa <pcmanticore@gmail.com> | 2019-05-21 09:16:32 +0200 |
---|---|---|
committer | Claudiu Popa <pcmanticore@gmail.com> | 2019-05-21 09:16:32 +0200 |
commit | 47d97c0bf2e7409fbc75645051ad20db2c298cb0 (patch) | |
tree | d72715ef95f39dfb77f1132de44399b9b93cac41 | |
parent | 5d0c0fa73bfc1c95f59b8d6e746117777681b260 (diff) | |
download | pylint-git-47d97c0bf2e7409fbc75645051ad20db2c298cb0.tar.gz |
Add a function to figure out if a node is a property setter and use it accordingly
-rw-r--r-- | pylint/checkers/base.py | 24 | ||||
-rw-r--r-- | pylint/checkers/classes.py | 10 | ||||
-rw-r--r-- | pylint/checkers/utils.py | 22 |
3 files changed, 32 insertions, 24 deletions
diff --git a/pylint/checkers/base.py b/pylint/checkers/base.py index 92cd6dfc7..e9aecb287 100644 --- a/pylint/checkers/base.py +++ b/pylint/checkers/base.py @@ -52,6 +52,7 @@ from astroid.arguments import CallSite import pylint.utils as lint_utils from pylint import checkers, exceptions, interfaces from pylint.checkers import utils +from pylint.checkers.utils import is_property_deleter, is_property_setter from pylint.reporters.ureports import nodes as reporter_nodes @@ -316,6 +317,12 @@ def _determine_function_name_type(node, config=None): property_classes, property_names = _get_properties(config) if not node.is_method(): return "function" + + if is_property_setter(node) or is_property_deleter(node): + # If the function is decorated using the prop_method.{setter,getter} + # form, treat it like an attribute as well. + return "attr" + if node.decorators: decorators = node.decorators.nodes else: @@ -330,13 +337,6 @@ def _determine_function_name_type(node, config=None): inferred = utils.safe_infer(decorator) if inferred and inferred.qname() in property_classes: return "attr" - # If the function is decorated using the prop_method.{setter,getter} - # form, treat it like an attribute as well. - elif isinstance(decorator, astroid.Attribute) and decorator.attrname in ( - "setter", - "deleter", - ): - return "attr" return "method" @@ -1915,19 +1915,11 @@ class DocStringChecker(_BasicChecker): if self.config.no_docstring_rgx.match(node.name) is None: self._check_docstring("class", node) - @staticmethod - def _is_setter_or_deleter(node): - names = {"setter", "deleter"} - for decorator in node.decorators.nodes: - if isinstance(decorator, astroid.Attribute) and decorator.attrname in names: - return True - return False - @utils.check_messages("missing-docstring", "empty-docstring") def visit_functiondef(self, node): if self.config.no_docstring_rgx.match(node.name) is None: ftype = "method" if node.is_method() else "function" - if node.decorators and self._is_setter_or_deleter(node): + if is_property_setter(node) or is_property_deleter(node): return if isinstance(node.parent.frame(), astroid.ClassDef): diff --git a/pylint/checkers/classes.py b/pylint/checkers/classes.py index ad54bcb48..df39331d3 100644 --- a/pylint/checkers/classes.py +++ b/pylint/checkers/classes.py @@ -55,6 +55,7 @@ from pylint.checkers.utils import ( is_builtin_object, is_comprehension, is_iterable, + is_property_setter, node_frame_class, overrides_a_method, safe_infer, @@ -1564,13 +1565,8 @@ a metaclass class method.", return # Ignore setters, they have an implicit extra argument, # which shouldn't be taken in consideration. - if method1.decorators: - for decorator in method1.decorators.nodes: - if ( - isinstance(decorator, astroid.Attribute) - and decorator.attrname == "setter" - ): - return + if is_property_setter(method1): + return if _different_parameters( refmethod, method1, dummy_parameter_regex=self._dummy_rgx diff --git a/pylint/checkers/utils.py b/pylint/checkers/utils.py index 2bb2d3585..9c4e71864 100644 --- a/pylint/checkers/utils.py +++ b/pylint/checkers/utils.py @@ -707,7 +707,7 @@ def error_of_type(handler: astroid.ExceptHandler, error_type) -> bool: def decorated_with_property(node: astroid.FunctionDef) -> bool: - """ Detect if the given function node is decorated with a property. """ + """Detect if the given function node is decorated with a property. """ if not node.decorators: return False for decorator in node.decorators.nodes: @@ -721,6 +721,26 @@ def decorated_with_property(node: astroid.FunctionDef) -> bool: return False +def _is_property_kind(node, kind): + if not isinstance(node, (astroid.UnboundMethod, astroid.FunctionDef)): + return False + if node.decorators: + for decorator in node.decorators.nodes: + if isinstance(decorator, astroid.Attribute) and decorator.attrname == kind: + return True + return False + + +def is_property_setter(node: astroid.FunctionDef) -> bool: + """Check if the given node is a property setter""" + return _is_property_kind(node, "setter") + + +def is_property_deleter(node: astroid.FunctionDef) -> bool: + """Check if the given node is a property deleter""" + return _is_property_kind(node, "deleter") + + def _is_property_decorator(decorator: astroid.Name) -> bool: for inferred in decorator.infer(): if isinstance(inferred, astroid.ClassDef): |