Spaces:
Sleeping
Sleeping
| """Complexity heuristics for Python code review.""" | |
| from __future__ import annotations | |
| import ast | |
| from typing import Any | |
| def _clamp_unit(value: float) -> float: | |
| return max(0.0, min(1.0, float(value))) | |
| def _estimate_time_complexity(loop_depth: int, uses_recursion: bool) -> str: | |
| if uses_recursion and loop_depth >= 1: | |
| return "O(n^2)" | |
| if loop_depth >= 3: | |
| return "O(n^3)" | |
| if loop_depth == 2: | |
| return "O(n^2)" | |
| if loop_depth == 1: | |
| return "O(n)" | |
| if uses_recursion: | |
| return "O(n)" | |
| return "O(1)" | |
| def _estimate_space_complexity(code: str, uses_recursion: bool) -> str: | |
| if uses_recursion: | |
| return "O(n)" | |
| if any(token in code for token in ("[]", "{}", "set(", "dict(", "list(", "Counter(")): | |
| return "O(n)" | |
| return "O(1)" | |
| def _cyclomatic_complexity(code: str) -> int: | |
| try: | |
| tree = ast.parse(code or "\n") | |
| except SyntaxError: | |
| return 1 | |
| decision_points = sum( | |
| isinstance(node, (ast.If, ast.For, ast.AsyncFor, ast.While, ast.Try, ast.ExceptHandler, ast.Match, ast.BoolOp)) | |
| for node in ast.walk(tree) | |
| ) | |
| return max(1, 1 + decision_points) | |
| def estimate_complexity(parsed: dict[str, Any], code: str) -> dict[str, Any]: | |
| """Estimate Python complexity signals from parsed structure plus source text.""" | |
| cyclomatic_complexity = _cyclomatic_complexity(code) | |
| loop_depth = int(parsed.get("max_loop_depth", 0) or 0) | |
| max_nesting_depth = int(parsed.get("max_nesting_depth", 0) or 0) | |
| uses_recursion = bool(parsed.get("uses_recursion", False)) | |
| line_count = int(parsed.get("line_count", 0) or 0) | |
| complexity_penalty = _clamp_unit( | |
| 0.08 | |
| + min(cyclomatic_complexity, 12) * 0.045 | |
| + min(loop_depth, 4) * 0.11 | |
| + min(max_nesting_depth, 4) * 0.06 | |
| + (0.06 if uses_recursion else 0.0) | |
| + min(line_count, 200) * 0.0009 | |
| ) | |
| return { | |
| "cyclomatic_complexity": cyclomatic_complexity, | |
| "time_complexity": _estimate_time_complexity(loop_depth, uses_recursion), | |
| "space_complexity": _estimate_space_complexity(code, uses_recursion), | |
| "complexity_penalty": round(complexity_penalty, 4), | |
| } | |