bazarr/tests/bazarr/test_all_import.py

107 lines
4.1 KiB
Python

#!/usr/bin/env python3
import os
import ast
from importlib.util import find_spec
bazarr_directory = os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(__file__))), "bazarr")
libs_directory = os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(__file__))), "libs")
def test_all_imports():
for root, dirs, files in os.walk(bazarr_directory):
for file in files:
if file.endswith(".py"):
modules = parse_imports(file=os.path.join(root, file))
check_for_import(imported_modules=modules, path=root, file=file)
def parse_imports(file):
with open(file, "r") as file:
node = ast.parse(file.read())
parsed_imports = [n.names[0].name for n in node.body if isinstance(n, ast.Import)]
parsed_from_imports = [(n.module, [x.name for x in n.names], n.level) for n in node.body if isinstance(n, ast.ImportFrom)]
return parsed_imports + parsed_from_imports
def get_valid_module_path(path, module, level):
module_file = os.path.sep.join(module.split("."))
# if relative import
if level:
relative_path = path
deep = level - 1
for number in range(deep):
relative_path = os.path.dirname(relative_path)
if os.path.isfile(os.path.join(relative_path, module_file + ".py")):
return os.path.join(relative_path, module_file + ".py")
else:
return os.path.join(relative_path, module_file, "__init__.py")
# elif bazarr dir + module.py isfile
elif os.path.isfile(os.path.join(bazarr_directory, module_file + ".py")):
return os.path.join(bazarr_directory, module_file + ".py")
# elif bazarr dir + module isdir
elif os.path.isdir(os.path.join(bazarr_directory, module_file)):
return os.path.join(bazarr_directory, module_file, "__init__.py")
# elif libs dir + module.py isfile
elif os.path.isfile(os.path.join(libs_directory, module_file + ".py")):
return os.path.join(libs_directory, module_file + ".py")
# elif libs dir + module isdir
elif os.path.isdir(os.path.join(libs_directory, module_file)):
return os.path.join(libs_directory, module_file, "__init__.py")
# else base module
else:
return None
def check_for_import(imported_modules, path, file):
print(os.path.join(path, file))
for module in imported_modules:
if module[1] == ["*"]:
continue
import_path = path
if type(module) == str:
module_name = module.strip()
functions_name = []
level = None
else:
try:
module_name = module[0].strip()
except AttributeError:
continue
functions_name = [x.strip() for x in module[1]]
level = module[2]
module_path = get_valid_module_path(import_path, module_name, level)
if not module_path:
try:
find_spec(module_name)
print("\tSUCCESS " + module_name)
continue
except Exception:
print("\tFAILED " + module_name)
raise ImportError
else:
# this is where we look into the included functions
print("\t" + module_name + f" ({module_path})")
with open(module_path, "r") as file:
node = ast.parse(file.read())
functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)]
classes = [n.name for n in node.body if isinstance(n, ast.ClassDef)]
assignments = [n.id for n in ast.walk(node) if isinstance(n, ast.Name)]
imports = [n.names[0].name for n in ast.walk(node) if isinstance(n, ast.Import)]
imports_from = []
for n in ast.walk(node):
if isinstance(n, ast.ImportFrom):
imports_from += [x.name for x in n.names]
for function in functions_name:
if [x for x in (functions, classes, assignments, imports, imports_from) if function in x]:
print("\t\tSUCCESS", function)
else:
print("\t\tFAILED", function)
raise ImportError