summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorClaudiu Popa <pcmanticore@gmail.com>2019-05-21 09:16:32 +0200
committerClaudiu Popa <pcmanticore@gmail.com>2019-05-21 09:16:32 +0200
commit47d97c0bf2e7409fbc75645051ad20db2c298cb0 (patch)
treed72715ef95f39dfb77f1132de44399b9b93cac41
parent5d0c0fa73bfc1c95f59b8d6e746117777681b260 (diff)
downloadpylint-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.py24
-rw-r--r--pylint/checkers/classes.py10
-rw-r--r--pylint/checkers/utils.py22
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):