summaryrefslogtreecommitdiff
path: root/pylint
diff options
context:
space:
mode:
authorClaudiu Popa <pcmanticore@gmail.com>2016-03-25 14:36:31 +0000
committerClaudiu Popa <pcmanticore@gmail.com>2016-03-25 14:36:31 +0000
commitad7c2cd38f7213edd1ff37aaead86d5ae8390df4 (patch)
tree476baae95554a44ca82c92be355af795c559ecbc /pylint
parent62a15879d84651490e00a0dfe97d20c2d9818e50 (diff)
downloadpylint-git-ad7c2cd38f7213edd1ff37aaead86d5ae8390df4.tar.gz
Add a new option, 'redefining-builtins-modules'.
The option can be used for controlling the modules which can redefine builtins, such as six.moves and future.builtins. Close #464.
Diffstat (limited to 'pylint')
-rw-r--r--pylint/checkers/variables.py19
-rw-r--r--pylint/test/unittest_checker_variables.py34
2 files changed, 50 insertions, 3 deletions
diff --git a/pylint/checkers/variables.py b/pylint/checkers/variables.py
index db03e3a9d..ee2a55792 100644
--- a/pylint/checkers/variables.py
+++ b/pylint/checkers/variables.py
@@ -339,7 +339,13 @@ class VariablesChecker(BaseChecker):
'help' : 'List of strings which can identify a callback '
'function by name. A callback name must start or '
'end with one of those strings.'}
- )
+ ),
+ ("redefining-builtins-modules",
+ {'default': ('six.moves', 'future.builtins'), 'type': 'csv',
+ 'metavar': '<comma separated list>',
+ 'help': 'List of qualified module names which can have objects '
+ 'that can redefine builtins.'}
+ ),
)
def __init__(self, linter=None):
BaseChecker.__init__(self, linter)
@@ -353,7 +359,8 @@ class VariablesChecker(BaseChecker):
self._to_consume = [(copy(node.locals), {}, 'module')]
for name, stmts in six.iteritems(node.locals):
if is_builtin(name) and not is_inside_except(stmts[0]):
- # do not print Redefining builtin for additional builtins
+ if self._should_ignore_redefined_builtin(stmts[0]):
+ continue
self.add_message('redefined-builtin', args=name, node=stmts[0])
@check_messages('unused-import', 'unused-wildcard-import',
@@ -552,7 +559,8 @@ class VariablesChecker(BaseChecker):
if not dummy_rgx.match(name):
self.add_message('redefined-outer-name',
args=(name, line), node=stmt)
- elif is_builtin(name):
+
+ elif is_builtin(name) and not self._should_ignore_redefined_builtin(stmt):
# do not print Redefining builtin for additional builtins
self.add_message('redefined-builtin', args=name, node=stmt)
@@ -737,6 +745,11 @@ class VariablesChecker(BaseChecker):
and assign.statement() is not node.statement()):
self.add_message('undefined-loop-variable', args=name, node=node)
+ def _should_ignore_redefined_builtin(self, stmt):
+ if not isinstance(stmt, astroid.ImportFrom):
+ return False
+ return stmt.modname in self.config.redefining_builtins_modules
+
@check_messages('redefine-in-handler')
def visit_excepthandler(self, node):
for name in get_all_elements(node.name):
diff --git a/pylint/test/unittest_checker_variables.py b/pylint/test/unittest_checker_variables.py
index e42dffcfd..141a34071 100644
--- a/pylint/test/unittest_checker_variables.py
+++ b/pylint/test/unittest_checker_variables.py
@@ -89,6 +89,40 @@ class VariablesCheckerTC(CheckerTestCase):
self.checker.visit_functiondef(node)
self.checker.leave_functiondef(node)
+ def test_redefined_builtin_ignored(self):
+ node = astroid.parse('''
+ from future.builtins import open
+ ''')
+ with self.assertNoMessages():
+ self.checker.visit_module(node)
+
+ @set_config(redefining_builtins_modules=('os',))
+ def test_redefined_builtin_custom_modules(self):
+ node = astroid.parse('''
+ from os import open
+ ''')
+ with self.assertNoMessages():
+ self.checker.visit_module(node)
+
+ @set_config(redefining_builtins_modules=('os',))
+ def test_redefined_builtin_modname_not_ignored(self):
+ node = astroid.parse('''
+ from future.builtins import open
+ ''')
+ with self.assertAddsMessages(
+ Message('redefined-builtin', node=node.body[0], args='open')):
+ self.checker.visit_module(node)
+
+ @set_config(redefining_builtins_modules=('os',))
+ def test_redefined_builtin_in_function(self):
+ node = test_utils.extract_node('''
+ def test():
+ from os import open
+ ''')
+ with self.assertNoMessages():
+ self.checker.visit_module(node.root())
+ self.checker.visit_functiondef(node)
+
class MissingSubmoduleTest(CheckerTestCase):
CHECKER_CLASS = variables.VariablesChecker