def main(): import optparse parser = optparse.OptionParser(__doc__.strip()) parser.add_option('--debug', action='store_true', help="Debugging output.") parser.add_option( '-I', '--ignore', dest='ignores', action='append', default=def_ignores, help="Add the given directory name to the list to be ignored.") parser.add_option( '-d', '--disable-pragmas', action='store_false', dest='do_pragmas', default=True, help="Disable processing of pragma directives as strings after imports." ) parser.add_option( '-D', '--duplicates', '--enable-duplicates', dest='do_dups', action='store_true', help="Enable experimental heuristic for finding duplicate imports.") parser.add_option( '-M', '--missing', '--enable-missing', dest='do_missing', action='store_true', help="Enable experimental heuristic for finding missing imports.") opts, args = parser.parse_args() write = sys.stderr.write for fn in iter_pyfiles(args or ['.'], opts.ignores, False): # Parse the file. ast, lines = parse_python_source(fn) if ast is None: continue found_imports = get_ast_imports(ast) # Check for duplicate remote names imported. if opts.do_dups: found_imports, dups = check_duplicate_imports(found_imports) for modname, rname, lname, lineno, level, pragma in dups: write("%s:%d: Duplicate import '%s'\n" % (fn, lineno, lname)) # Filter out the unused imports. used_imports, unused_imports = filter_unused_imports( ast, found_imports) # Output warnings for the unused imports. for x in unused_imports: _, _, lname, lineno, _, pragma = x if opts.do_pragmas and pragma: continue # Search for the column in the relevant line. mo = re.search(r'\b%s\b' % lname, lines[lineno - 1]) colno = 0 if mo: colno = mo.start() + 1 write("%s:%d:%d: Unused import '%s'\n" % (fn, lineno, colno, lname)) # (Optionally) Compute the list of names that are being assigned to. if opts.do_missing or opts.debug: vis = AssignVisitor() ast.walk(ast, vis) assign_names = vis.finalize() # (Optionally) Check for potentially missing imports (this cannot be # precise, we are only providing a heuristic here). if opts.do_missing: defined = set(modname for modname, _, _, _, _, _ in used_imports) defined.update(x[0] for x in assign_names) _, simple_names = get_names_from_ast(ast) for name, lineno in simple_names: if name not in defined and name not in builtins.__dict__: write("%s:%d: Missing import for '%s'\n" % (fn, lineno, name)) # Print out all the schmoo for debugging. if opts.debug: print_() print_() print_('------ Imported names:') for modname, rname, lname, lineno, level, pragma in found_imports: print_('%s:%d: %s' % (fn, lineno, lname)) ## print_() ## print_() ## print_('------ Exported names:') ## for name, lineno in exported: ## print_('%s:%d: %s' % (fn, lineno, name)) ## print_() ## print_() ## print_('------ Used names:') ## for name, lineno in dotted_names: ## print_('%s:%d: %s' % (fn, lineno, name)) ## print_() print_() print_() print_('------ Assigned names:') for name, lineno in assign_names: print_('%s:%d: %s' % (fn, lineno, name)) print_() print_() print_('------ AST:') printAst(ast, indent=' ', stream=sys.stdout, initlevel=1) print_()
def main(): import optparse parser = optparse.OptionParser(__doc__.strip()) parser.add_option('--debug', action='store_true', help="Debugging output.") parser.add_option('-I', '--ignore', dest='ignores', action='append', default=def_ignores, help="Add the given directory name to the list to be ignored.") parser.add_option('-d', '--disable-pragmas', action='store_false', dest='do_pragmas', default=True, help="Disable processing of pragma directives as strings after imports.") parser.add_option('-D', '--duplicates', '--enable-duplicates', dest='do_dups', action='store_true', help="Enable experimental heuristic for finding duplicate imports.") parser.add_option('-M', '--missing', '--enable-missing', dest='do_missing', action='store_true', help="Enable experimental heuristic for finding missing imports.") opts, args = parser.parse_args() write = sys.stderr.write for fn in iter_pyfiles(args or ['.'], opts.ignores, False): # Parse the file. ast, lines = parse_python_source(fn) if ast is None: continue found_imports = get_ast_imports(ast) # Check for duplicate remote names imported. if opts.do_dups: found_imports, dups = check_duplicate_imports(found_imports) for modname, rname, lname, lineno, level, pragma in dups: write("%s:%d: Duplicate import '%s'\n" % (fn, lineno, lname)) # Filter out the unused imports. used_imports, unused_imports = filter_unused_imports(ast, found_imports) # Output warnings for the unused imports. for x in unused_imports: _, _, lname, lineno, _, pragma = x if opts.do_pragmas and pragma: continue # Search for the column in the relevant line. mo = re.search(r'\b%s\b' % lname, lines[lineno-1]) colno = 0 if mo: colno = mo.start()+1 write("%s:%d:%d: Unused import '%s'\n" % (fn, lineno, colno, lname)) # (Optionally) Compute the list of names that are being assigned to. if opts.do_missing or opts.debug: vis = AssignVisitor() compiler.walk(ast, vis) assign_names = vis.finalize() # (Optionally) Check for potentially missing imports (this cannot be # precise, we are only providing a heuristic here). if opts.do_missing: defined = set(modname for modname, _, _, _, _, _ in used_imports) defined.update(x[0] for x in assign_names) for name, lineno in simple_names: if name not in defined and name not in __builtin__.__dict__: write("%s:%d: Missing import for '%s'\n" % (fn, lineno, name)) # Print out all the schmoo for debugging. if opts.debug: print print print '------ Imported names:' for modname, rname, lname, lineno, level, pragma in found_imports: print '%s:%d: %s' % (fn, lineno, lname) ## print ## print ## print '------ Exported names:' ## for name, lineno in exported: ## print '%s:%d: %s' % (fn, lineno, name) ## print ## print ## print '------ Used names:' ## for name, lineno in dotted_names: ## print '%s:%d: %s' % (fn, lineno, name) ## print print print print '------ Assigned names:' for name, lineno in assign_names: print '%s:%d: %s' % (fn, lineno, name) print print print '------ AST:' printAst(ast, indent=' ', stream=sys.stdout, initlevel=1) print