diff options
author | Claudiu Popa <cpopa@cloudbasesolutions.com> | 2015-04-24 11:09:36 +0300 |
---|---|---|
committer | Claudiu Popa <cpopa@cloudbasesolutions.com> | 2015-04-24 11:09:36 +0300 |
commit | 2714f46c74bfedcb29626465a90c1c41194bc8db (patch) | |
tree | f6d0eaa34b4561eaa4587e5015c37b86adaf21c4 | |
parent | 3c6818dcfbb61007cbf092d10c849be13e4e28c4 (diff) | |
download | pylint-2714f46c74bfedcb29626465a90c1c41194bc8db.tar.gz |
Move more no-member filters inside _emit_no_member. Add more tests.
-rw-r--r-- | pylint/checkers/typecheck.py | 29 | ||||
-rw-r--r-- | pylint/test/functional/member_checks.py | 28 | ||||
-rw-r--r-- | pylint/test/functional/member_checks.txt | 2 |
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 |