diff options
author | cpopa <devnull@localhost> | 2014-07-17 23:31:24 +0300 |
---|---|---|
committer | cpopa <devnull@localhost> | 2014-07-17 23:31:24 +0300 |
commit | d61747ad0031f10f06145cc848d6d13c089f292f (patch) | |
tree | ef3f73e3034965c2a9125c3888eeb261b30dbfe5 | |
parent | 235ee6dd14de0678d4f219bd57624c10af816cd0 (diff) | |
download | pylint-d61747ad0031f10f06145cc848d6d13c089f292f.tar.gz |
Fix an 'unused-variable' false positive, where the variable is assigned through an import. Closes issue #196.
-rw-r--r-- | ChangeLog | 3 | ||||
-rw-r--r-- | checkers/variables.py | 42 | ||||
-rw-r--r-- | test/input/func_w0612.py | 18 | ||||
-rw-r--r-- | test/messages/func_w0612.txt | 8 |
4 files changed, 67 insertions, 4 deletions
@@ -36,6 +36,9 @@ ChangeLog for Pylint * Don't emit 'no-name-in-module' for ignored modules. Closes issue #223. + * Fix an 'unused-variable' false positive, where the variable is + assigned through an import. Closes issue #196. + 2014-04-30 -- 1.2.1 * Restore the ability to specify the init-hook option via the configuration file, which was accidentally broken in 1.2.0. diff --git a/checkers/variables.py b/checkers/variables.py index 6cbcdb6..94a8d6e 100644 --- a/checkers/variables.py +++ b/checkers/variables.py @@ -356,6 +356,10 @@ builtins. Remember that you should avoid to define new builtins when possible.' authorized_rgx = self.config.dummy_variables_rgx called_overridden = False argnames = node.argnames() + global_names = set() + for global_stmt in node.nodes_of_class(astroid.Global): + global_names.update(set(global_stmt.names)) + for name, stmts in not_consumed.iteritems(): # ignore some special names specified by user configuration if authorized_rgx.match(name): @@ -365,6 +369,23 @@ builtins. Remember that you should avoid to define new builtins when possible.' stmt = stmts[0] if isinstance(stmt, astroid.Global): continue + if isinstance(stmt, (astroid.Import, astroid.From)): + # Detect imports, assigned to global statements. + if global_names: + skip = False + for import_name, import_alias in stmt.names: + # If the import uses an alias, check only that. + # Otherwise, check only the import name. + if import_alias: + if import_alias in global_names: + skip = True + break + elif import_name in global_names: + skip = True + break + if skip: + continue + # care about functions with unknown argument (builtins) if name in argnames: if is_method: @@ -412,7 +433,26 @@ builtins. Remember that you should avoid to define new builtins when possible.' break else: # global but no assignment - self.add_message('global-variable-not-assigned', args=name, node=node) + # Detect imports in the current frame, with the required + # name. Such imports can be considered assignments. + imports = frame.nodes_of_class((astroid.Import, astroid.From)) + for import_node in imports: + found = False + for import_name, import_alias in import_node.names: + # If the import uses an alias, check only that. + # Otherwise, check only the import name. + if import_alias: + if import_alias == name: + found = True + break + elif import_name and import_name == name: + found = True + break + if found: + break + else: + self.add_message('global-variable-not-assigned', + args=name, node=node) default_message = False if not assign_nodes: continue diff --git a/test/input/func_w0612.py b/test/input/func_w0612.py index 57e139c..e871bb2 100644 --- a/test/input/func_w0612.py +++ b/test/input/func_w0612.py @@ -1,7 +1,8 @@ """test unused variable """ - +# pylint: disable=invalid-name, redefined-outer-name __revision__ = 0 +PATH = OS = collections = deque = None def function(matches): """"yo""" @@ -20,3 +21,18 @@ def visit_if(self, node): self.inc_branch(branches) self.stmts += branches +def test_global(): + """ Test various assignments of global + variables through imports. + """ + global PATH, OS, collections, deque + from os import path as PATH + import os as OS + import collections + from collections import deque + # make sure that these triggers unused-variable + from sys import platform + from sys import version as VERSION + import this + import re as RE + diff --git a/test/messages/func_w0612.txt b/test/messages/func_w0612.txt index f1647a3..c81b4f9 100644 --- a/test/messages/func_w0612.txt +++ b/test/messages/func_w0612.txt @@ -1,2 +1,6 @@ -W: 8:function: Unused variable 'aaaa' -W: 9:function: Unused variable 'index' +W: 9:function: Unused variable 'aaaa' +W: 10:function: Unused variable 'index' +W: 34:test_global: Unused variable 'platform' +W: 35:test_global: Unused variable 'VERSION' +W: 36:test_global: Unused variable 'this' +W: 37:test_global: Unused variable 'RE' |