68 lines
2.1 KiB
Python
68 lines
2.1 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
Quick utility: count function definitions in Python files.
|
|
Extracts function names and counts, outputs JSON report.
|
|
"""
|
|
|
|
import ast
|
|
import json
|
|
import os
|
|
import sys
|
|
from pathlib import Path
|
|
from collections import Counter
|
|
from typing import Dict, List, Any
|
|
|
|
|
|
def extract_functions(filepath: str) -> List[str]:
|
|
"""Extract function names from a Python file using AST parsing."""
|
|
try:
|
|
with open(filepath, 'r', encoding='utf-8') as f:
|
|
content = f.read()
|
|
tree = ast.parse(content, filename=filepath)
|
|
functions = []
|
|
for node in ast.walk(tree):
|
|
if isinstance(node, ast.FunctionDef):
|
|
functions.append(node.name)
|
|
elif isinstance(node, ast.AsyncFunctionDef):
|
|
functions.append(node.name)
|
|
return functions
|
|
except (SyntaxError, UnicodeDecodeError, FileNotFoundError) as e:
|
|
return []
|
|
|
|
|
|
def scan_directory(directory: str, extensions: List[str] = None) -> Dict[str, Any]:
|
|
"""Scan a directory for Python files and extract function counts."""
|
|
if extensions is None:
|
|
extensions = ['.py']
|
|
|
|
all_functions = []
|
|
files_scanned = 0
|
|
|
|
for root, dirs, files in os.walk(directory):
|
|
for filename in files:
|
|
if any(filename.endswith(ext) for ext in extensions):
|
|
filepath = os.path.join(root, filename)
|
|
functions = extract_functions(filepath)
|
|
if functions:
|
|
all_functions.extend(functions)
|
|
for func in functions:
|
|
print(f"{filepath}: {func}")
|
|
files_scanned += 1
|
|
|
|
function_counts = Counter(all_functions)
|
|
|
|
return {
|
|
"directory": directory,
|
|
"files_scanned": files_scanned,
|
|
"total_function_definitions": len(all_functions),
|
|
"unique_functions": len(function_counts),
|
|
"top_functions": dict(function_counts.most_common(10))
|
|
}
|
|
|
|
|
|
if __name__ == "__main__":
|
|
target = sys.argv[1] if len(sys.argv) > 1 else "/root"
|
|
|
|
result = scan_directory(target)
|
|
print("\n--- REPORT ---")
|
|
print(json.dumps(result, indent=2)) |