forked from Tribler/tribler-utils
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathimport_extractor.py
58 lines (52 loc) · 1.88 KB
/
import_extractor.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
import ast
import distutils.sysconfig as sysconfig
import imp
import pathlib
import pkgutil
import os
import sys
built_in_modules = set(sys.builtin_module_names)
built_in_modules.update({
module
for _, module, package in pkgutil.iter_modules()
if package is False
})
std_lib = sysconfig.get_python_lib(standard_lib=True)
for top in pathlib.Path(std_lib).iterdir():
if str(top).startswith(('dist-packages', 'site-packages')):
continue
built_in_modules.add(str(top).split('.')[0])
external_modules = set()
def is_external_module(top_path, path, name):
"""
Check if we can import this module from somewhere in the local file structure.
(Filter out imports within the workspace)
"""
if not name:
return
name = name.split('.')[0]
if name not in built_in_modules:
try:
imp.find_module(name, [os.path.dirname(path), path, top_path])
except ImportError:
external_modules.add(name)
location = os.path.abspath(sys.argv[1])
for dirpath, dirnames, filenames in os.walk(location):
py_filenames = [filename for filename in filenames if filename.endswith('.py')]
for filename in py_filenames:
with pathlib.Path(dirpath, filename).open() as file:
file_contents = file.read()
if not file_contents:
continue
try:
node = ast.parse(file_contents)
for subnode in ast.walk(node):
if isinstance(subnode, ast.Import):
for import_name in (alias.name for alias in subnode.names):
is_external_module(location, dirpath, import_name)
if isinstance(subnode, ast.ImportFrom):
is_external_module(location, dirpath, subnode.module)
except:
print("ERROR: Failed to parse", filename, file=sys.stderr)
for name in sorted(external_modules):
print(name)