From d61747ad0031f10f06145cc848d6d13c089f292f Mon Sep 17 00:00:00 2001 From: cpopa Date: Thu, 17 Jul 2014 23:31:24 +0300 Subject: Fix an 'unused-variable' false positive, where the variable is assigned through an import. Closes issue #196. --- checkers/variables.py | 42 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 41 insertions(+), 1 deletion(-) (limited to 'checkers') 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 -- cgit v1.2.1