summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHolger Peters <holger.peters@blue-yonder.com>2014-04-17 08:28:26 +0200
committerHolger Peters <holger.peters@blue-yonder.com>2014-04-17 08:28:26 +0200
commitf30918424c0dcef79e5506f93fb3d904a18f905b (patch)
tree544919d3e05f95bcc9a3bdcc77313f4588b302a3
parentb0b935b8f61d602baf56cfd0370a5a289311f2d3 (diff)
parentc09bd81358c7265d4305075825bd1540baaae836 (diff)
downloadpylint-f30918424c0dcef79e5506f93fb3d904a18f905b.tar.gz
Merged logilab/pylint into default
-rw-r--r--checkers/typecheck.py14
-rw-r--r--test/test_type.py55
2 files changed, 66 insertions, 3 deletions
diff --git a/checkers/typecheck.py b/checkers/typecheck.py
index 0d4b13b..ec44f8d 100644
--- a/checkers/typecheck.py
+++ b/checkers/typecheck.py
@@ -133,7 +133,15 @@ class TypeChecker(BaseChecker):
class should be ignored. A mixin class is detected if its name ends with \
"mixin" (case insensitive).'}
),
-
+ ('ignored-modules',
+ {'default': ('optparse',),
+ 'type': 'csv',
+ 'metavar': '<module names>',
+ 'help': 'List of module names for which member attributes \
+should not be checked (useful for modules/projects where namespaces are \
+manipulated during runtime and thus extisting member attributes cannot be \
+deduced by static analysis'},
+ ),
('ignored-classes',
{'default' : ('SQLObject',),
'type' : 'csv',
@@ -230,8 +238,8 @@ accessed. Python regular expressions are accepted.'}
continue
if isinstance(owner, Instance) and owner.has_dynamic_getattr():
continue
- # explicit skipping of optparse'Values class
- if owner.name == 'Values' and owner.root().name == 'optparse':
+ # explicit skipping of module member access
+ if owner.root().name in self.config.ignored_modules:
continue
missingattr.add((owner, name))
continue
diff --git a/test/test_type.py b/test/test_type.py
new file mode 100644
index 0000000..7c65215
--- /dev/null
+++ b/test/test_type.py
@@ -0,0 +1,55 @@
+"""Unittest for the type checker."""
+
+from astroid import test_utils
+from pylint.checkers import typecheck
+from pylint.testutils import CheckerTestCase, Message, set_config
+
+class TypeCheckerTest(CheckerTestCase):
+ "Tests for pylint.checkers.typecheck"
+ CHECKER_CLASS = typecheck.TypeChecker
+
+ def test_no_member_in_getattr(self):
+ """Make sure that a module attribute access is checked by pylint.
+ """
+
+ node = test_utils.extract_node("""
+ import argparse
+ argparse.THIS_does_not_EXIST
+ """)
+ with self.assertAddsMessages(
+ Message(
+ 'no-member',
+ node=node,
+ args=('Module', 'argparse', 'THIS_does_not_EXIST'))):
+ self.checker.visit_getattr(node)
+
+ def test_no_member_in_getattr_ignored(self):
+ """Make sure that a module attribute access check is omitted with a
+ module that is configured to be ignored.
+ """
+
+ node = test_utils.extract_node("""
+ import optparse
+ optparse.THIS_does_not_EXIST
+ """)
+ with self.assertNoMessages():
+ self.checker.visit_getattr(node)
+
+
+ @set_config(ignored_modules=('argparse',))
+ def test_no_member_in_getattr_ignored_cust_config(self):
+ """Make sure that a module can be added to the ignored_modules list and
+ a no-member message will not be raised upon attribute access.
+ """
+
+ node = test_utils.extract_node("""
+ import argparse
+ argparse.THIS_does_not_EXIST
+ """)
+ with self.assertNoMessages():
+ self.checker.visit_getattr(node)
+
+
+if __name__ == '__main__':
+ from logilab.common.testlib import unittest_main
+ unittest_main()