From f44c9a1cdcf3c9983a712672e0342cb8dd489f7a Mon Sep 17 00:00:00 2001 From: cpopa Date: Fri, 2 May 2014 09:36:01 +0300 Subject: Fix unused-import false positive with Python 3 metaclasses. Closes issue #143. --- ChangeLog | 3 +++ checkers/variables.py | 16 ++++++++++++++++ test/input/func_unused_import_py30.py | 20 ++++++++++++++++++++ test/messages/func_unused_import_py30.txt | 6 ++++++ 4 files changed, 45 insertions(+) create mode 100644 test/input/func_unused_import_py30.py create mode 100644 test/messages/func_unused_import_py30.txt diff --git a/ChangeLog b/ChangeLog index da62285..9b675d0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,9 @@ ChangeLog for Pylint ==================== +-- + * Fix unused-import false positive with Python 3 metaclasses (#143). + 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 a6123de..dc8d111 100644 --- a/checkers/variables.py +++ b/checkers/variables.py @@ -716,6 +716,22 @@ class VariablesChecker3k(VariablesChecker): # do not check for not used locals here self._to_consume.pop() + def leave_module(self, node): + """ Update consumption analysis variable + for metaclasses. + """ + for klass in node.nodes_of_class(astroid.Class): + if klass._metaclass: + metaclass = klass.metaclass() + module_locals = self._to_consume[0][0] + + if isinstance(klass._metaclass, astroid.Name): + module_locals.pop(klass._metaclass.name, None) + if metaclass: + # if it uses a `metaclass=module.Class` + module_locals.pop(metaclass.root().name, None) + super(VariablesChecker3k, self).leave_module(node) + if sys.version_info >= (3, 0): VariablesChecker = VariablesChecker3k diff --git a/test/input/func_unused_import_py30.py b/test/input/func_unused_import_py30.py new file mode 100644 index 0000000..ae6db93 --- /dev/null +++ b/test/input/func_unused_import_py30.py @@ -0,0 +1,20 @@ +"""check unused import for metaclasses +""" +__revision__ = 1 +import abc +import sys +from abc import ABCMeta +from abc import ABCMeta as SomethingElse + +class Meta(metaclass=abc.ABCMeta): + """ Test """ + def __init__(self): + self.data = sys.executable + self.test = abc + +class Meta2(metaclass=ABCMeta): + """ Test """ + +class Meta3(metaclass=SomethingElse): + """ test """ + diff --git a/test/messages/func_unused_import_py30.txt b/test/messages/func_unused_import_py30.txt new file mode 100644 index 0000000..72a21fe --- /dev/null +++ b/test/messages/func_unused_import_py30.txt @@ -0,0 +1,6 @@ +R: 9:Meta: Too few public methods (0/2) +R: 15:Meta2: Too few public methods (0/2) +R: 18:Meta3: Too few public methods (0/2) +W: 7: Reimport 'ABCMeta' (imported line 6) +W: 15:Meta2: Class has no __init__ method +W: 18:Meta3: Class has no __init__ method \ No newline at end of file -- cgit v1.2.1