summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorClaudiu Popa <cpopa@cloudbasesolutions.com>2015-02-05 01:15:17 +0200
committerClaudiu Popa <cpopa@cloudbasesolutions.com>2015-02-05 01:15:17 +0200
commit0963c1ff552782a9e4d18d653c330ea58937d47d (patch)
treea753c86e725039c17e12ea5ece64bd5f262d6822
parent2e1f5afab2497baf2a9e1fe47fed62482da3cfcc (diff)
downloadpylint-0963c1ff552782a9e4d18d653c330ea58937d47d.tar.gz
Look all the methods from ancestors for too-few-public-methods.
This patch uses two counters for too-few-public-methods and too-many-public-methods. In order to avoid false positives, too-many-public-methods check is looking only for methods defined in the current class. On the other hand, too-few-public-methods should look in ancestors as well, since most of the time this check is useful only for simple classes, without many public methods. Closes issue #471.
-rw-r--r--ChangeLog3
-rw-r--r--checkers/design_analysis.py35
-rw-r--r--test/input/func_r0903.py16
3 files changed, 40 insertions, 14 deletions
diff --git a/ChangeLog b/ChangeLog
index c51942d..4c93046 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -10,6 +10,9 @@ ChangeLog for Pylint
an attribute access ('{0.__class__}').
Closes issue #463.
+ * Take in account all the methods from the ancestors
+ when checking for too-few-public-methods. Closes issue #471.
+
2015-01-16 -- 1.4.1
diff --git a/checkers/design_analysis.py b/checkers/design_analysis.py
index 0a7a307..e361cca 100644
--- a/checkers/design_analysis.py
+++ b/checkers/design_analysis.py
@@ -234,28 +234,35 @@ class MisdesignChecker(BaseChecker):
except KeyError:
self._used_abstracts[parent] = 1
- @check_messages('too-many-ancestors', 'too-many-instance-attributes',
- 'too-few-public-methods', 'too-many-public-methods',
- 'abstract-class-not-used', 'abstract-class-little-used',
- 'interface-not-implemented')
+ @check_messages('too-few-public-methods', 'too-many-public-methods')
def leave_class(self, node):
"""check number of public methods"""
- nb_public_methods = 0
- for method in node.mymethods():
- if not method.name.startswith('_'):
- nb_public_methods += 1
- # Does the class contain less than 20 public methods ?
- if nb_public_methods > self.config.max_public_methods:
+ my_methods = sum(1 for method in node.mymethods()
+ if not method.name.startswith('_'))
+ all_methods = sum(1 for method in node.methods()
+ if not method.name.startswith('_'))
+
+ # Does the class contain less than n public methods ?
+ # This checks only the methods defined in the current class,
+ # since the user might not have control over the classes
+ # from the ancestors. It avoids some false positives
+ # for classes such as unittest.TestCase, which provides
+ # a lot of assert methods. It doesn't make sense to warn
+ # when the user subclasses TestCase to add his own tests.
+ if my_methods > self.config.max_public_methods:
self.add_message('too-many-public-methods', node=node,
- args=(nb_public_methods,
+ args=(my_methods,
self.config.max_public_methods))
# stop here for exception, metaclass and interface classes
if node.type != 'class':
return
- # Does the class contain more than 5 public methods ?
- if nb_public_methods < self.config.min_public_methods:
+
+ # Does the class contain more than n public methods ?
+ # This checks all the methods defined by ancestors and
+ # by the current class.
+ if all_methods < self.config.min_public_methods:
self.add_message('too-few-public-methods', node=node,
- args=(nb_public_methods,
+ args=(all_methods,
self.config.min_public_methods))
@check_messages('too-many-return-statements', 'too-many-branches',
diff --git a/test/input/func_r0903.py b/test/input/func_r0903.py
index 917b0ea..49008f9 100644
--- a/test/input/func_r0903.py
+++ b/test/input/func_r0903.py
@@ -12,3 +12,19 @@ class Aaaa(object):
def _dontcount(self):
"""not public"""
print(self)
+
+
+# Don't emit for these cases.
+class Klass(object):
+ """docstring"""
+
+ def meth1(self):
+ """first"""
+
+ def meth2(self):
+ """second"""
+
+
+class EnoughPublicMethods(Klass):
+ """We shouldn't emit too-few-public-methods for this."""
+