VultureChecker/vulture.py

changeset 18
e19e7622a428
parent 7
a1a6ff3e5486
child 39
445ed09016ce
--- a/VultureChecker/vulture.py	Fri Oct 09 19:00:49 2015 +0200
+++ b/VultureChecker/vulture.py	Sun Oct 11 19:29:38 2015 +0200
@@ -40,6 +40,11 @@
 # Parse variable names in template strings.
 FORMAT_STRING_PATTERNS = [re.compile(r'\%\((\w+)\)'), re.compile(r'{(\w+)}')]
 
+IGNORED_VARIABLE_NAMES = ['object']
+# True and False are NameConstants since Python 3.4.
+if sys.version_info < (3, 4):
+    IGNORED_VARIABLE_NAMES += ['True', 'False']
+
 
 def _ignore_function(name):
     return ((name.startswith('__') and name.endswith('__')) or
@@ -47,10 +52,10 @@
 
 
 class Item(str):
-    def __new__(cls, name, typ, file, lineno):
+    def __new__(cls, name, typ, filename, lineno):
         item = str.__new__(cls, name)
         item.typ = typ
-        item.file = file
+        item.filename = filename
         item.lineno = lineno
         return item
 
@@ -76,12 +81,13 @@
         self.tuple_assign_vars = []
         self.names_imported_as_aliases = []
 
-        self.file = ''
+        self.filename = ''
         self.code = None
 
-    def scan(self, node_string):
+    def scan(self, node_string, filename=''):
         self.code = node_string.splitlines()
-        node = ast.parse(node_string, filename=self.file)
+        self.filename=filename
+        node = ast.parse(node_string, filename=self.filename)
         self.visit(node)
 
     def _get_modules(self, paths, toplevel=True):
@@ -112,20 +118,19 @@
             self.log('Scanning:', module)
             with open(module) as f:
                 module_string = f.read()
-            self.file = module
-            self.scan(module_string)
+            self.scan(module_string, filename=module)
 
     def report(self):
         def file_lineno(item):
-            return (item.file.lower(), item.lineno)
+            return (item.filename.lower(), item.lineno)
         unused_item_found = False
         for item in sorted(self.unused_funcs + self.unused_props +
                            self.unused_vars + self.unused_attrs,
                            key=file_lineno):
-            relpath = os.path.relpath(item.file)
-            path = relpath if not relpath.startswith('..') else item.file
-            print("%s:%d: Unused %s '%s'" % (path, item.lineno, item.typ,
-                                             item))
+            relpath = os.path.relpath(item.filename)
+            path = relpath if not relpath.startswith('..') else item.filename
+            print(
+                "%s:%d: Unused %s '%s'" % (path, item.lineno, item.typ, item))
             unused_item_found = True
         return unused_item_found
 
@@ -151,7 +156,8 @@
 
     @property
     def unused_attrs(self):
-        return self.get_unused(self.defined_attrs, self.used_attrs)
+        return self.get_unused(self.defined_attrs,
+                               self.used_attrs + self.used_vars)
 
     def _get_lineno(self, node):
         return getattr(node, 'lineno', 1)
@@ -161,10 +167,10 @@
 
     def _get_item(self, node, typ):
         name = getattr(node, 'name', None)
-        id = getattr(node, 'id', None)
+        id_ = getattr(node, 'id', None)
         attr = getattr(node, 'attr', None)
-        assert len([x for x in (name, id, attr) if x is not None]) == 1
-        return Item(name or id or attr, typ, self.file, node.lineno)
+        assert bool(name) ^ bool(id_) ^ bool(attr)
+        return Item(name or id_ or attr, typ, self.filename, node.lineno)
 
     def log(self, *args):
         if self.verbose:
@@ -203,7 +209,7 @@
             self.used_attrs.append(item)
 
     def visit_Name(self, node):
-        if node.id != 'object':
+        if node.id not in IGNORED_VARIABLE_NAMES:
             if isinstance(node.ctx, ast.Load):
                 self.log('used_vars <-', node.id)
                 self.used_vars.append(node.id)

eric ide

mercurial