Skip to content

Instantly share code, notes, and snippets.

@graingert
Last active April 10, 2019 12:56
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 graingert/8527424b86ead59713fb96e04e6d5d2a to your computer and use it in GitHub Desktop.
Save graingert/8527424b86ead59713fb96e04e6d5d2a to your computer and use it in GitHub Desktop.
import_finder.py
import pathlib
import ast
def _packages(path):
return _include_parents(path.with_suffix('').parts)
def _include_parents(parts):
p = list(parts)
while p:
mod = tuple(p)
yield mod
if mod and not mod[-1] == '__init__':
yield mod + ('__init__', )
p.pop()
def _split(mod):
return tuple(mod.split('.')) if mod else ()
def parse_imports(path):
t = path.read_text('utf8', 'surrogateescape')
packages = _packages(path)
package = next(packages)
yield package
yield from packages
for stmt in ast.parse(t).body:
if isinstance(stmt, ast.Import):
for alias in stmt.names:
yield from _include_parents(_split(alias.name))
if isinstance(stmt, ast.ImportFrom):
root = package[:-stmt.level] + _split(stmt.module)
for alias in stmt.names:
yield from _include_parents(root + _split(alias.name))
def main():
seen = set()
roots = set()
for p in pathlib.Path('odc').glob('**/*.py'):
imports = list(parse_imports(p))
package = imports[0]
roots -= set(imports)
if package not in seen:
roots.add(package)
seen |= set(imports)
print(sorted('.'.join(m) for m in roots))
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment