Load all Python functions from functions directory.
(self)
| 40 | self._loaded = False |
| 41 | |
| 42 | def load_functions(self) -> None: |
| 43 | """Load all Python functions from functions directory.""" |
| 44 | if self._loaded: |
| 45 | return |
| 46 | |
| 47 | if not self.functions_dir.exists(): |
| 48 | raise ValueError(f"Functions directory does not exist: {self.functions_dir}") |
| 49 | |
| 50 | for file in self.functions_dir.rglob("*.py"): |
| 51 | if file.name.startswith("_") or file.name == "__init__.py": |
| 52 | continue |
| 53 | if "__pycache__" in file.parts: |
| 54 | continue |
| 55 | |
| 56 | module_name = self._build_module_name(file) |
| 57 | try: |
| 58 | # Import module dynamically |
| 59 | spec = importlib.util.spec_from_file_location(module_name, file) |
| 60 | if spec is None or spec.loader is None: |
| 61 | continue |
| 62 | |
| 63 | module = importlib.util.module_from_spec(spec) |
| 64 | spec.loader.exec_module(module) |
| 65 | |
| 66 | current_file = file.resolve() |
| 67 | # Get all functions defined in the module |
| 68 | for name, obj in inspect.getmembers(module, inspect.isfunction): |
| 69 | if name.startswith("_"): |
| 70 | continue |
| 71 | # Only register functions defined in the current module/file |
| 72 | if getattr(obj, "__module__", None) != module.__name__: |
| 73 | code = getattr(obj, "__code__", None) |
| 74 | source_path = Path(code.co_filename).resolve() if code else None |
| 75 | if source_path != current_file: |
| 76 | continue |
| 77 | self.functions[name] = obj |
| 78 | except Exception as e: |
| 79 | print(f"Error loading module {module_name}: {e}") |
| 80 | |
| 81 | self._loaded = True |
| 82 | |
| 83 | def _build_module_name(self, filepath: Path) -> str: |
| 84 | """Create a unique module name for a function file.""" |
no test coverage detected