fix: resolve CI type checking and lint failures
Some checks failed
CI / test (push) Has been cancelled
CI / build (push) Has been cancelled

This commit is contained in:
2026-01-30 17:19:20 +00:00
parent 316a389abf
commit 4e90bd776e

View File

@@ -0,0 +1,110 @@
"""Circular dependency detection utilities."""
from pathlib import Path
from typing import Any, Optional
from .graph import DependencyGraph
class CycleDetector:
"""Detector for circular dependencies in codebases."""
def __init__(self, graph: DependencyGraph):
self.graph = graph
def detect_all_cycles(self) -> list[list[Path]]:
"""Detect all cycles in the dependency graph."""
return self.graph.detect_cycles()
def detect_cycles_for_file(self, file_path: Path) -> list[list[Path]]:
"""Detect cycles that include a specific file."""
all_cycles = self.detect_all_cycles()
return [
cycle for cycle in all_cycles if file_path in cycle
]
def get_cyclic_files(self) -> list[Path]:
"""Get all files that are part of a cycle."""
cyclic_files = set()
for cycle in self.detect_all_cycles():
cyclic_files.update(cycle)
return list(cyclic_files)
def is_cyclic(self, file_path: Path) -> bool:
"""Check if a specific file is part of a cycle."""
return file_path in self.get_cyclic_files()
def get_cycle_chains(self) -> dict[Path, list[list[Path]]]:
"""Get all cycles grouped by their involved files."""
chains: dict[Path, list[list[Path]]] = {}
for cycle in self.detect_all_cycles():
for file in cycle:
if file not in chains:
chains[file] = []
chains[file].append(cycle)
return chains
def get_report(self) -> dict[str, Any]:
"""Generate a comprehensive cycle detection report."""
cycles = self.detect_all_cycles()
cyclic_files = self.get_cyclic_files()
report = {
"total_cycles": len(cycles),
"cyclic_files": len(cyclic_files),
"cyclic_file_names": [str(f) for f in cyclic_files],
"cycles": [
[str(f) for f in cycle] for cycle in cycles
],
"severity": self._calculate_severity(cycles),
}
return report
def _calculate_severity(
self, cycles: list[list[Path]]
) -> str:
"""Calculate the severity of the cyclic dependencies."""
if not cycles:
return "none"
max_cycle_length = max(len(c) for c in cycles) if cycles else 0
if max_cycle_length > 10:
return "critical"
elif max_cycle_length > 5:
return "high"
elif len(cycles) > 5:
return "medium"
return "low"
def export_cycle_report(self, path: Path) -> None:
"""Export the cycle report to a file."""
import json
report = self.get_report()
with open(path, "w") as f:
json.dump(report, f, indent=2)
def find_cyclic_dependencies(
project_root: Path,
extensions: Optional[list[str]] = None,
) -> list[list[Path]]:
"""Convenience function to find cyclic dependencies."""
graph = DependencyGraph(project_root)
graph.build_from_directory(extensions=extensions)
detector = CycleDetector(graph)
return detector.detect_all_cycles()
def get_cyclic_file_report(
project_root: Path,
) -> dict[str, Any]:
"""Generate a report on cyclic dependencies for a project."""
graph = DependencyGraph(project_root)
graph.build_from_directory()
detector = CycleDetector(graph)
return detector.get_report()