Skip to content

Instantly share code, notes, and snippets.

Created June 28, 2014 18:10
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save anonymous/d51e06375bdf8513ca61 to your computer and use it in GitHub Desktop.
Save anonymous/d51e06375bdf8513ca61 to your computer and use it in GitHub Desktop.
Count imports in *.py files in a given directory recursively.
#!/usr/bin/env python
"""Count imports in *.py files in a given directory recursively.
Each name is counted once per file.
"""
import ast
import os
import sys
from collections import Counter
def get_imports(python_text):
"""Yield full import names from python_text."""
try:
root = ast.parse(python_text)
except (SyntaxError, TypeError):
return # no imports
for node in ast.walk(root):
if isinstance(node, (ast.Import, ast.ImportFrom)):
prefix = getattr(node, 'module', None)
for name in (alias.name for alias in node.names):
yield name if prefix is None else '.'.join([prefix, name])
def main():
# count all imports in topdir directory
topdir = '.' if len(sys.argv) < 2 else sys.argv[1]
freq = Counter() # imported name -> number of occurrences
for rootdir, dirs, files in os.walk(topdir):
for filename in files:
if filename.endswith('.py'):
path = os.path.join(rootdir, filename)
try:
file = open(path, 'rb')
except IOError:
continue
else:
with file:
file_imports = Counter()
for qname in get_imports(file.read()):
# count all parts of the fully-qualified name
s = ''
while qname:
part, _, qname = qname.partition('.')
s += '.' * bool(s) + part
file_imports[s] = 1 # one import per file
freq += file_imports
for name, count in freq.most_common():
print("%s\t%s" % (name, count))
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment