summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorClaudiu Popa <cpopa@cloudbasesolutions.com>2015-04-24 11:09:36 +0300
committerClaudiu Popa <cpopa@cloudbasesolutions.com>2015-04-24 11:09:36 +0300
commit2714f46c74bfedcb29626465a90c1c41194bc8db (patch)
treef6d0eaa34b4561eaa4587e5015c37b86adaf21c4
parent3c6818dcfbb61007cbf092d10c849be13e4e28c4 (diff)
downloadpylint-2714f46c74bfedcb29626465a90c1c41194bc8db.tar.gz
Move more no-member filters inside _emit_no_member. Add more tests.
-rw-r--r--pylint/checkers/typecheck.py29
-rw-r--r--pylint/test/functional/member_checks.py28
-rw-r--r--pylint/test/functional/member_checks.txt2
3 files changed, 44 insertions, 15 deletions
diff --git a/pylint/checkers/typecheck.py b/pylint/checkers/typecheck.py
index d0d3027..1e9b004 100644
--- a/pylint/checkers/typecheck.py
+++ b/pylint/checkers/typecheck.py
@@ -89,7 +89,8 @@ SEQUENCE_TYPES = set(['str', 'unicode', 'list', 'tuple', 'bytearray',
'xrange', 'range', 'bytes', 'memoryview'])
-def _emit_no_member(owner, owner_name, attrname, ignored_modules, ignored_mixins):
+def _emit_no_member(owner, owner_name, attrname,
+ ignored_modules, ignored_mixins, ignored_classes):
"""Try to see if no-member should be emitted for the given owner.
The following cases are ignored:
@@ -99,6 +100,14 @@ def _emit_no_member(owner, owner_name, attrname, ignored_modules, ignored_mixins
* the module is explicitly ignored from no-member checks
* the owner is a class and the name can be found in its metaclass.
"""
+ if owner_name in ignored_classes:
+ return False
+ # skip None anyway
+ if isinstance(owner, astroid.Const) and owner.value is None:
+ return False
+ # TODO(cpopa): This should be removed when we'll understand "super"
+ if is_super(owner) or getattr(owner, 'type', None) == 'metaclass':
+ return False
if ignored_mixins and owner_name[-5:].lower() == 'mixin':
return False
if isinstance(owner, astroid.Function) and owner.decorators:
@@ -272,15 +281,7 @@ accessed. Python regular expressions are accepted.'}
if owner is YES:
inference_failure = True
continue
- # skip None anyway
- if isinstance(owner, astroid.Const) and owner.value is None:
- continue
- # XXX "super" / metaclass call
- if is_super(owner) or getattr(owner, 'type', None) == 'metaclass':
- continue
name = getattr(owner, 'name', 'None')
- if name in self.config.ignored_classes:
- continue
try:
if not [n for n in owner.getattr(node.attrname)
if not isinstance(n.statement(), astroid.AugAssign)]:
@@ -290,10 +291,12 @@ accessed. Python regular expressions are accepted.'}
# XXX method / function
continue
except NotFoundError:
- if _emit_no_member(owner, name, node.attrname,
- self.config.ignored_modules,
- self.config.ignore_mixin_members):
- missingattr.add((owner, name))
+ if not _emit_no_member(owner, name, node.attrname,
+ self.config.ignored_modules,
+ self.config.ignore_mixin_members,
+ self.config.ignored_classes):
+ continue
+ missingattr.add((owner, name))
continue
# stop on the first found
break
diff --git a/pylint/test/functional/member_checks.py b/pylint/test/functional/member_checks.py
index c112425..38a3488 100644
--- a/pylint/test/functional/member_checks.py
+++ b/pylint/test/functional/member_checks.py
@@ -1,4 +1,4 @@
-# pylint: disable=print-statement
+# pylint: disable=print-statement,missing-docstring,no-self-use,too-few-public-methods
"""check getattr if inference succeed"""
from __future__ import print_function
@@ -58,6 +58,32 @@ class Client(object):
integer = 1
print(integer.whatever) # [no-member]
+ def test_no_false_positives(self):
+ none = None
+ print(none.whatever)
+ # This will be handled when we'll understand super
+ super(Client, self).misssing()
+
+
+class Mixin(object):
+ """No no-member should be emitted for mixins."""
+
+class Getattr(object):
+ """no-member shouldn't be emitted for classes with dunder getattr."""
+
+ def __getattr__(self, attr):
+ return self.__dict__[attr]
+
+
+class Getattribute(object):
+ """no-member shouldn't be emitted for classes with dunder getattribute."""
+
+ def __getattribute__(self, attr):
+ return 42
+
print(object.__init__)
print(property.__init__)
print(Client().set_later.lower()) # [no-member]
+print(Mixin().nanana())
+print(Getattr().nananan())
+print(Getattribute().batman())
diff --git a/pylint/test/functional/member_checks.txt b/pylint/test/functional/member_checks.txt
index 12fe6ee..9b4d258 100644
--- a/pylint/test/functional/member_checks.txt
+++ b/pylint/test/functional/member_checks.txt
@@ -6,4 +6,4 @@ no-member:53:Client.test_bt_types:Instance of 'dict' has no 'set' member:INFEREN
no-member:55:Client.test_bt_types:Instance of 'tuple' has no 'append' member:INFERENCE
no-member:57:Client.test_bt_types:Instance of 'str' has no 'loower' member:INFERENCE
no-member:59:Client.test_bt_types:Instance of 'int' has no 'whatever' member:INFERENCE
-no-member:63::Instance of 'int' has no 'lower' member:INFERENCE_FAILURE
+no-member:86::Instance of 'int' has no 'lower' member:INFERENCE_FAILURE