| 77 | |
| 78 | |
| 79 | class ModelAnalyzer(ast.NodeVisitor): |
| 80 | def __init__(self): |
| 81 | self.model_classes = [] |
| 82 | self.current_class = None |
| 83 | self.imports = set() |
| 84 | |
| 85 | def visit_Import(self, node: ast.Import): |
| 86 | for alias in node.names: |
| 87 | self.imports.add(alias.name.split(".")[-1]) |
| 88 | self.generic_visit(node) |
| 89 | |
| 90 | def visit_ImportFrom(self, node: ast.ImportFrom): |
| 91 | for alias in node.names: |
| 92 | self.imports.add(alias.name) |
| 93 | self.generic_visit(node) |
| 94 | |
| 95 | def visit_ClassDef(self, node: ast.ClassDef): |
| 96 | base_names = [] |
| 97 | for base in node.bases: |
| 98 | if isinstance(base, ast.Name): |
| 99 | base_names.append(base.id) |
| 100 | elif isinstance(base, ast.Attribute): |
| 101 | base_names.append(base.attr) |
| 102 | |
| 103 | if "ModelMixin" in base_names: |
| 104 | class_info = { |
| 105 | "name": node.name, |
| 106 | "bases": base_names, |
| 107 | "attributes": {}, |
| 108 | "has_forward": False, |
| 109 | "init_params": [], |
| 110 | } |
| 111 | |
| 112 | for item in node.body: |
| 113 | if isinstance(item, ast.Assign): |
| 114 | for target in item.targets: |
| 115 | if isinstance(target, ast.Name): |
| 116 | attr_name = target.id |
| 117 | if attr_name.startswith("_"): |
| 118 | class_info["attributes"][attr_name] = self._get_value(item.value) |
| 119 | |
| 120 | elif isinstance(item, ast.FunctionDef): |
| 121 | if item.name == "forward": |
| 122 | class_info["has_forward"] = True |
| 123 | class_info["forward_params"] = self._extract_func_params(item) |
| 124 | elif item.name == "__init__": |
| 125 | class_info["init_params"] = self._extract_func_params(item) |
| 126 | |
| 127 | self.model_classes.append(class_info) |
| 128 | |
| 129 | self.generic_visit(node) |
| 130 | |
| 131 | def _extract_func_params(self, func_node: ast.FunctionDef) -> list[dict]: |
| 132 | params = [] |
| 133 | args = func_node.args |
| 134 | |
| 135 | num_defaults = len(args.defaults) |
| 136 | num_args = len(args.args) |
no outgoing calls
searching dependent graphs…