Skip to content

Instantly share code, notes, and snippets.

@bnlucas
Created June 22, 2015 06:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bnlucas/51515509ed9015e659dd to your computer and use it in GitHub Desktop.
Save bnlucas/51515509ed9015e659dd to your computer and use it in GitHub Desktop.
Find all .py files that import a certain module or just supplied methods of the module. I use http://click.pocoo.org/ for interacting with the command line, but this can be changed.
import os
import re
from subprocess import PIPE, Popen
import click
def which(executable):
for path in os.environ['PATH'].split(os.pathsep):
path = path.strip('"')
fpath = os.path.join(path, executable)
if os.path.isfile(fpath) and os.access(fpath, os.X_OK):
return fpath
if os.name == 'nt' and not executable.endswith('.exe'):
return which('{}.exe'.format(executable))
return None
def find_files(pattern, path, exts=('.py')):
pattern = re.compile(pattern)
found = []
path = os.path.realpath(path)
for root, dirnames, files in os.walk(path):
for fname in files:
if fname.endswith(exts):
with open(os.path.join(root, fname), 'r') as f:
if any(pattern.search(line) for line in f):
found.append(os.path.join(root, fname))
break
return sorted(found)
def grep_files(pattern, path, exts=('.py')):
path = os.path.realpath(path)
grep = '''grep -E "{}" * -lr'''.format(pattern)
proc = Popen(grep, shell=True, cwd=path, stdout=PIPE, stderr=PIPE)
out, err = proc.communicate()
if err:
print err
if not out:
return None
out = out.decode('utf8')
found = []
for f in out.split():
if f.endswith(exts):
found.append(os.path.join(path, f.replace('/', os.sep)))
return sorted(found)
def find_module(module, path, methods=[]):
if len(methods) != 0:
pattern = ''
i = 0
for method in methods:
pattern += '''from {} import {}'''.format(module, method)
if i < len(methods) - 1:
pattern += '|'
i += 1
else:
pattern = '''import {0}|from {0}'''.format(module)
if which('grep'):
return grep_files(pattern, path)
return find_files(pattern, path)
@click.command()
@click.argument('module')
@click.option('--path', '-p', default='./', help='project path')
@click.option('--methods', '-m', multiple=True, help='method imported')
def module_finder(module, path, methods):
click.clear()
click.echo('searching {} for imports of...\n'.format(os.path.realpath(path)))
if methods:
click.echo(' OR\n'.join([' {}.{}'.format(module, m) for m in methods]))
else:
click.echo(' {}'.format(module))
click.echo('')
click.echo('-' * 80)
click.echo('')
files = find_module(module, path, methods)
if files:
for f in files:
click.echo(f)
else:
click.echo('no files found.')
click.echo('')
click.echo('-' * 80)
if __name__ == '__main__':
module_finder()
'''
c:\projects\python\sandbox>imports.py fontaispy.numbers.stubs -m ceil -m gcd
searching c:\projects\python\sandbox for imports of...
fontaispy.numbers.stubs.ceil OR
fontaispy.numbers.stubs.gcd
--------------------------------------------------------------------------------
c:\projects\python\sandbox\fontaispy\benchmark.py
c:\projects\python\sandbox\fontaispy\numbers\primes.py
--------------------------------------------------------------------------------
c\projects\python\sandbox>
'''
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment