summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSylvain Th?nault <sylvain.thenault@logilab.fr>2013-07-17 12:08:02 +0200
committerSylvain Th?nault <sylvain.thenault@logilab.fr>2013-07-17 12:08:02 +0200
commitcf74f295ec39224c36d20422d52051e4544e0eb8 (patch)
treeceb46d962624a02ff4e5065da8ac53f8d385fdf9
parentf1b2a96fc423abb5d5bb48626300231e143c61cf (diff)
downloadpylint-cf74f295ec39224c36d20422d52051e4544e0eb8.tar.gz
[design analysis] fix badly implemented protocol for read-only containers like tuple. Close #25
-rw-r--r--ChangeLog3
-rw-r--r--checkers/design_analysis.py11
-rw-r--r--test/input/func_special_methods.py16
-rw-r--r--test/messages/func_special_methods.txt7
4 files changed, 24 insertions, 13 deletions
diff --git a/ChangeLog b/ChangeLog
index a756db8..3bfb10d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -86,6 +86,9 @@ ChangeLog for Pylint
* bitbucket #37: check for unbalanced unpacking in assignments
+ * bitbucket #25: fix incomplete-protocol false positive for read-only
+ containers like tuple
+
* bitbucket #16: fix False positive E1003 on Python 3 for argument-less super()
* bitbucket #6: put back documentation in source distribution
diff --git a/checkers/design_analysis.py b/checkers/design_analysis.py
index 5e60ccb..f3b5882 100644
--- a/checkers/design_analysis.py
+++ b/checkers/design_analysis.py
@@ -29,10 +29,9 @@ IGNORED_ARGUMENT_NAMES = re.compile('_.*')
SPECIAL_METHODS = [('Context manager', set(('__enter__',
'__exit__',))),
('Container', set(('__len__',
- '__getitem__',
- '__setitem__',
- '__delitem__',))),
- ('Callable', set(('__call__',))),
+ '__getitem__',))),
+ ('Mutable container', set(('__setitem__',
+ '__delitem__',))),
]
class SpecialMethodChecker(object):
@@ -56,8 +55,8 @@ class SpecialMethodChecker(object):
required_methods_found = methods_required & self.methods_found
if required_methods_found == methods_required:
return True
- if required_methods_found != set():
- required_methods_missing = methods_required - self.methods_found
+ if required_methods_found:
+ required_methods_missing = methods_required - self.methods_found
self.on_error((protocol,
', '.join(sorted(required_methods_found)),
', '.join(sorted(required_methods_missing))))
diff --git a/test/input/func_special_methods.py b/test/input/func_special_methods.py
index 29bb3d4..1b30e26 100644
--- a/test/input/func_special_methods.py
+++ b/test/input/func_special_methods.py
@@ -29,7 +29,7 @@ class Container(object):
def __iter__(self):
pass
-class BadContainer(object):
+class BadROContainer(object):
def __init__(self):
pass
def __len__(self):
@@ -39,9 +39,17 @@ class BadContainer(object):
def __iter__(self):
pass
-class Callable(object):
- def __call__(self):
- pass
+
+class BadContainer(object):
def __init__(self):
pass
+ def __len__(self):
+ return 0
+ def __getitem__(self, key, value):
+ pass
+ def __setitem__(self, key, value):
+ pass
+class MyTuple(tuple):
+ def __getitem__(self, index):
+ return super(MyTuple, self).__getitem__(index)
diff --git a/test/messages/func_special_methods.txt b/test/messages/func_special_methods.txt
index 3add213..f7e88ae 100644
--- a/test/messages/func_special_methods.txt
+++ b/test/messages/func_special_methods.txt
@@ -1,5 +1,6 @@
R: 12:BadContextManager: Badly implemented Context manager, implements __enter__ but not __exit__
R: 12:BadContextManager: Too few public methods (0/2)
-R: 32:BadContainer: Badly implemented Container, implements __len__, __setitem__ but not __delitem__, __getitem__
-R: 32:BadContainer: Too few public methods (0/2)
-
+R: 32:BadROContainer: Badly implemented Container, implements __len__ but not __getitem__
+R: 32:BadROContainer: Badly implemented Mutable container, implements __setitem__ but not __delitem__
+R: 32:BadROContainer: Too few public methods (0/2)
+R: 43:BadContainer: Badly implemented Mutable container, implements __setitem__ but not __delitem__