analysts / app /analyzer.py
Shinhati2023's picture
Create app/analyzer.py
b76a728 verified
import ast
from typing import List, Dict
class CodeSmellVisitor(ast.NodeVisitor):
def __init__(self):
self.issues = []
def visit_FunctionDef(self, node):
"""Check for functions with too many arguments (Code Smell)"""
if len(node.args.args) > 5:
self.issues.append({
"line": node.lineno,
"type": "Complexity",
"message": f"Function '{node.name}' has too many arguments ({len(node.args.args)}). Max is 5."
})
# Check for mutable default arguments (e.g., def foo(l=[]))
# This is a classic Python 'gotcha' interview question
for default in node.args.defaults:
if isinstance(default, (ast.List, ast.Dict, ast.Set)):
self.issues.append({
"line": node.lineno,
"type": "Bug Risk",
"message": f"Function '{node.name}' uses a mutable default argument. This persists state across calls!"
})
# Continue walking through the children of this node
self.generic_visit(node)
def visit_Call(self, node):
"""Check for dangerous function calls like eval()"""
if isinstance(node.func, ast.Name) and node.func.id == 'eval':
self.issues.append({
"line": node.lineno,
"type": "Security",
"message": "Use of 'eval()' detected. This is a major security risk."
})
self.generic_visit(node)
def analyze_code(code_content: str) -> List[Dict]:
try:
tree = ast.parse(code_content)
visitor = CodeSmellVisitor()
visitor.visit(tree)
return visitor.issues
except SyntaxError as e:
return [{"line": e.lineno, "type": "Syntax Error", "message": str(e)}]