mirror of
https://github.com/tiennm99/litellm.git
synced 2026-07-11 05:03:57 +00:00
style: run black formatter on files from main merge
This commit is contained in:
@@ -6,7 +6,7 @@ def check_for_litellm_module_deletion(base_dir):
|
||||
"""
|
||||
Checks for code patterns that delete litellm modules from sys.modules
|
||||
in the test_litellm directory.
|
||||
|
||||
|
||||
Specifically looks for patterns like:
|
||||
for module in list(sys.modules.keys()):
|
||||
if module.startswith("litellm"):
|
||||
@@ -14,13 +14,13 @@ def check_for_litellm_module_deletion(base_dir):
|
||||
"""
|
||||
problematic_files = []
|
||||
test_dir = os.path.join(base_dir, "test_litellm")
|
||||
|
||||
|
||||
if not os.path.exists(test_dir):
|
||||
print(f"Warning: Directory {test_dir} does not exist.")
|
||||
return []
|
||||
|
||||
print(f"Checking directory: {test_dir}")
|
||||
|
||||
|
||||
for root, _, files in os.walk(test_dir):
|
||||
for file in files:
|
||||
if file.endswith(".py"):
|
||||
@@ -31,132 +31,143 @@ def check_for_litellm_module_deletion(base_dir):
|
||||
except SyntaxError:
|
||||
print(f"Warning: Syntax error in file {file_path}")
|
||||
continue
|
||||
|
||||
|
||||
# Check for litellm module deletion patterns
|
||||
if has_litellm_module_deletion(tree):
|
||||
relative_path = os.path.relpath(file_path, base_dir)
|
||||
problematic_files.append(relative_path)
|
||||
print(f"Found litellm module deletion in: {relative_path}")
|
||||
|
||||
|
||||
return problematic_files
|
||||
|
||||
|
||||
def has_litellm_module_deletion(tree):
|
||||
"""
|
||||
Checks if the AST contains patterns that delete litellm modules from sys.modules.
|
||||
|
||||
|
||||
Looks for:
|
||||
1. Loops over sys.modules.keys()
|
||||
2. Conditions checking if module startswith "litellm"
|
||||
3. del sys.modules[module] statements
|
||||
"""
|
||||
|
||||
class LiteLLMDeletionVisitor(ast.NodeVisitor):
|
||||
def __init__(self):
|
||||
self.has_sys_modules_loop = False
|
||||
self.has_litellm_check = False
|
||||
self.has_del_sys_modules = False
|
||||
self.current_for_target = None
|
||||
|
||||
|
||||
def visit_For(self, node):
|
||||
# Check if we're looping over sys.modules.keys()
|
||||
if (isinstance(node.iter, ast.Call) and
|
||||
isinstance(node.iter.func, ast.Attribute) and
|
||||
isinstance(node.iter.func.value, ast.Attribute) and
|
||||
isinstance(node.iter.func.value.value, ast.Name) and
|
||||
node.iter.func.value.value.id == "sys" and
|
||||
node.iter.func.value.attr == "modules" and
|
||||
node.iter.func.attr == "keys"):
|
||||
|
||||
if (
|
||||
isinstance(node.iter, ast.Call)
|
||||
and isinstance(node.iter.func, ast.Attribute)
|
||||
and isinstance(node.iter.func.value, ast.Attribute)
|
||||
and isinstance(node.iter.func.value.value, ast.Name)
|
||||
and node.iter.func.value.value.id == "sys"
|
||||
and node.iter.func.value.attr == "modules"
|
||||
and node.iter.func.attr == "keys"
|
||||
):
|
||||
|
||||
self.has_sys_modules_loop = True
|
||||
if isinstance(node.target, ast.Name):
|
||||
self.current_for_target = node.target.id
|
||||
|
||||
|
||||
# Check the body of the for loop
|
||||
for stmt in node.body:
|
||||
self.visit(stmt)
|
||||
|
||||
|
||||
# Also check for list(sys.modules.keys()) pattern
|
||||
elif (isinstance(node.iter, ast.Call) and
|
||||
isinstance(node.iter.func, ast.Name) and
|
||||
node.iter.func.id == "list" and
|
||||
len(node.iter.args) == 1 and
|
||||
isinstance(node.iter.args[0], ast.Call) and
|
||||
isinstance(node.iter.args[0].func, ast.Attribute) and
|
||||
isinstance(node.iter.args[0].func.value, ast.Attribute) and
|
||||
isinstance(node.iter.args[0].func.value.value, ast.Name) and
|
||||
node.iter.args[0].func.value.value.id == "sys" and
|
||||
node.iter.args[0].func.value.attr == "modules" and
|
||||
node.iter.args[0].func.attr == "keys"):
|
||||
|
||||
elif (
|
||||
isinstance(node.iter, ast.Call)
|
||||
and isinstance(node.iter.func, ast.Name)
|
||||
and node.iter.func.id == "list"
|
||||
and len(node.iter.args) == 1
|
||||
and isinstance(node.iter.args[0], ast.Call)
|
||||
and isinstance(node.iter.args[0].func, ast.Attribute)
|
||||
and isinstance(node.iter.args[0].func.value, ast.Attribute)
|
||||
and isinstance(node.iter.args[0].func.value.value, ast.Name)
|
||||
and node.iter.args[0].func.value.value.id == "sys"
|
||||
and node.iter.args[0].func.value.attr == "modules"
|
||||
and node.iter.args[0].func.attr == "keys"
|
||||
):
|
||||
|
||||
self.has_sys_modules_loop = True
|
||||
if isinstance(node.target, ast.Name):
|
||||
self.current_for_target = node.target.id
|
||||
|
||||
|
||||
# Check the body of the for loop
|
||||
for stmt in node.body:
|
||||
self.visit(stmt)
|
||||
|
||||
|
||||
self.generic_visit(node)
|
||||
|
||||
|
||||
def visit_If(self, node):
|
||||
# Check for conditions like module.startswith("litellm")
|
||||
if (isinstance(node.test, ast.Call) and
|
||||
isinstance(node.test.func, ast.Attribute) and
|
||||
isinstance(node.test.func.value, ast.Name) and
|
||||
node.test.func.value.id == self.current_for_target and
|
||||
node.test.func.attr == "startswith" and
|
||||
len(node.test.args) == 1 and
|
||||
isinstance(node.test.args[0], ast.Constant) and
|
||||
node.test.args[0].value == "litellm"):
|
||||
|
||||
if (
|
||||
isinstance(node.test, ast.Call)
|
||||
and isinstance(node.test.func, ast.Attribute)
|
||||
and isinstance(node.test.func.value, ast.Name)
|
||||
and node.test.func.value.id == self.current_for_target
|
||||
and node.test.func.attr == "startswith"
|
||||
and len(node.test.args) == 1
|
||||
and isinstance(node.test.args[0], ast.Constant)
|
||||
and node.test.args[0].value == "litellm"
|
||||
):
|
||||
|
||||
self.has_litellm_check = True
|
||||
|
||||
|
||||
# Check the body of the if statement
|
||||
for stmt in node.body:
|
||||
self.visit(stmt)
|
||||
|
||||
|
||||
self.generic_visit(node)
|
||||
|
||||
|
||||
def visit_Delete(self, node):
|
||||
# Check for del sys.modules[module]
|
||||
for target in node.targets:
|
||||
if (isinstance(target, ast.Subscript) and
|
||||
isinstance(target.value, ast.Attribute) and
|
||||
isinstance(target.value.value, ast.Name) and
|
||||
target.value.value.id == "sys" and
|
||||
target.value.attr == "modules" and
|
||||
isinstance(target.slice, ast.Name) and
|
||||
target.slice.id == self.current_for_target):
|
||||
|
||||
if (
|
||||
isinstance(target, ast.Subscript)
|
||||
and isinstance(target.value, ast.Attribute)
|
||||
and isinstance(target.value.value, ast.Name)
|
||||
and target.value.value.id == "sys"
|
||||
and target.value.attr == "modules"
|
||||
and isinstance(target.slice, ast.Name)
|
||||
and target.slice.id == self.current_for_target
|
||||
):
|
||||
|
||||
self.has_del_sys_modules = True
|
||||
|
||||
|
||||
self.generic_visit(node)
|
||||
|
||||
|
||||
visitor = LiteLLMDeletionVisitor()
|
||||
visitor.visit(tree)
|
||||
|
||||
return (visitor.has_sys_modules_loop and
|
||||
visitor.has_litellm_check and
|
||||
visitor.has_del_sys_modules)
|
||||
|
||||
return (
|
||||
visitor.has_sys_modules_loop
|
||||
and visitor.has_litellm_check
|
||||
and visitor.has_del_sys_modules
|
||||
)
|
||||
|
||||
|
||||
def main():
|
||||
"""
|
||||
Main function to check for litellm module deletion patterns in test files.
|
||||
"""
|
||||
# local dir
|
||||
#tests_dir = "../../tests/"
|
||||
|
||||
# local dir
|
||||
# tests_dir = "../../tests/"
|
||||
|
||||
# ci/cd dir
|
||||
tests_dir = "./tests/"
|
||||
|
||||
|
||||
problematic_files = check_for_litellm_module_deletion(tests_dir)
|
||||
|
||||
|
||||
if problematic_files:
|
||||
print("\nERROR: Found files that delete litellm modules from sys.modules:")
|
||||
for file_path in problematic_files:
|
||||
print(f" - {file_path}")
|
||||
|
||||
|
||||
raise Exception(
|
||||
f"Found {len(problematic_files)} file(s) that delete litellm modules from sys.modules. "
|
||||
f"This can cause import issues and test failures. Files: {problematic_files}"
|
||||
|
||||
Reference in New Issue
Block a user