Download code_analyzer.py from prelington/PyPilot: direct link, hf CLI and curl.
- Browser
- Download file 7.46 kB
-
https://huggingface.co/prelington/PyPilot/resolve/0e4d8606368df6c0ecc0df7044547b9aba2dbd69/code_analyzer.py
- Command line
-
hf download hf://prelington/PyPilot@0e4d8606368df6c0ecc0df7044547b9aba2dbd69/code_analyzer.py
-
curl -L -o code_analyzer.py https://huggingface.co/prelington/PyPilot/resolve/0e4d8606368df6c0ecc0df7044547b9aba2dbd69/code_analyzer.py
7.46 kB
| """ | |
| PyPilot Code Analyzer - Advanced static analysis and quality metrics | |
| """ | |
| import ast | |
| import astor | |
| import radon | |
| from radon import metrics, complexity | |
| from radon.visitors import ComplexityVisitor | |
| import lizard | |
| import tempfile | |
| import subprocess | |
| import os | |
| class PyPilotCodeAnalyzer: | |
| def __init__(self): | |
| self.analysis_results = {} | |
| def comprehensive_analysis(self, code_string): | |
| """Perform comprehensive code analysis""" | |
| analysis = {} | |
| try: | |
| # Parse AST | |
| tree = ast.parse(code_string) | |
| analysis['ast_info'] = self.analyze_ast(tree) | |
| # Code metrics | |
| analysis['metrics'] = self.calculate_metrics(code_string) | |
| # Complexity analysis | |
| analysis['complexity'] = self.analyze_complexity(code_string) | |
| # Security checks | |
| analysis['security'] = self.security_scan(code_string) | |
| # Code quality | |
| analysis['quality'] = self.quality_assessment(code_string) | |
| except Exception as e: | |
| analysis['error'] = str(e) | |
| return analysis | |
| def analyze_ast(self, tree): | |
| """Analyze Abstract Syntax Tree""" | |
| ast_info = { | |
| 'imports': [], | |
| 'functions': [], | |
| 'classes': [], | |
| 'variables': [], | |
| 'structure': {} | |
| } | |
| for node in ast.walk(tree): | |
| if isinstance(node, ast.Import): | |
| for alias in node.names: | |
| ast_info['imports'].append(alias.name) | |
| elif isinstance(node, ast.ImportFrom): | |
| ast_info['imports'].append(f"from {node.module}") | |
| elif isinstance(node, ast.FunctionDef): | |
| ast_info['functions'].append({ | |
| 'name': node.name, | |
| 'args': [arg.arg for arg in node.args.args], | |
| 'lineno': node.lineno | |
| }) | |
| elif isinstance(node, ast.ClassDef): | |
| ast_info['classes'].append({ | |
| 'name': node.name, | |
| 'bases': [base.id for base in node.bases if hasattr(base, 'id')], | |
| 'lineno': node.lineno | |
| }) | |
| elif isinstance(node, ast.Assign): | |
| for target in node.targets: | |
| if hasattr(target, 'id'): | |
| ast_info['variables'].append(target.id) | |
| return ast_info | |
| def calculate_metrics(self, code_string): | |
| """Calculate comprehensive code metrics""" | |
| with tempfile.NamedTemporaryFile(mode='w', suffix='.py', delete=False) as f: | |
| f.write(code_string) | |
| temp_file = f.name | |
| try: | |
| # Use lizard for advanced metrics | |
| analysis = lizard.analyze_file(temp_file) | |
| metrics = { | |
| 'lines_of_code': analysis.nloc, | |
| 'token_count': analysis.token_count, | |
| 'function_count': len(analysis.function_list), | |
| 'average_complexity': analysis.average_cyclomatic_complexity, | |
| 'maintainability_index': analysis.maintainability_index, | |
| } | |
| # Function-level metrics | |
| functions_metrics = [] | |
| for func in analysis.function_list: | |
| functions_metrics.append({ | |
| 'name': func.name, | |
| 'complexity': func.cyclomatic_complexity, | |
| 'lines': func.length, | |
| 'parameters': func.parameter_count | |
| }) | |
| metrics['functions'] = functions_metrics | |
| finally: | |
| os.unlink(temp_file) | |
| return metrics | |
| def analyze_complexity(self, code_string): | |
| """Analyze code complexity using radon""" | |
| try: | |
| cc = complexity.cc_visit(code_string) | |
| complexity_data = [] | |
| for block in cc: | |
| complexity_data.append({ | |
| 'name': block.name, | |
| 'complexity': block.complexity, | |
| 'type': block.type, | |
| 'lineno': block.lineno | |
| }) | |
| mi = metrics.mi_visit(code_string, True) | |
| return { | |
| 'cyclomatic_complexity': complexity_data, | |
| 'maintainability_index': mi, | |
| 'halstead_metrics': metrics.h_visit(code_string) | |
| } | |
| except Exception as e: | |
| return {'error': str(e)} | |
| def security_scan(self, code_string): | |
| """Basic security vulnerability scan""" | |
| vulnerabilities = [] | |
| security_patterns = [ | |
| ('eval', 'Use of eval() function'), | |
| ('exec', 'Use of exec() function'), | |
| ('pickle.loads', 'Unsafe deserialization'), | |
| ('os.system', 'Potential command injection'), | |
| ('subprocess.call', 'Potential command injection'), | |
| ] | |
| for pattern, description in security_patterns: | |
| if pattern in code_string: | |
| vulnerabilities.append({ | |
| 'type': 'security', | |
| 'description': description, | |
| 'severity': 'high' | |
| }) | |
| return vulnerabilities | |
| def quality_assessment(self, code_string): | |
| """Assess code quality""" | |
| quality_score = 100 | |
| # Check for common issues | |
| issues = [] | |
| if len(code_string) > 1000: | |
| issues.append("File is too long") | |
| quality_score -= 10 | |
| if code_string.count('\n') > 50: | |
| issues.append("Too many lines") | |
| quality_score -= 5 | |
| # Check for commented code | |
| if code_string.count('#') > code_string.count('\n') * 0.3: | |
| issues.append("Too many comments") | |
| quality_score -= 5 | |
| return { | |
| 'quality_score': max(quality_score, 0), | |
| 'issues': issues, | |
| 'recommendations': self.generate_recommendations(issues) | |
| } | |
| def generate_recommendations(self, issues): | |
| """Generate improvement recommendations""" | |
| recommendations = [] | |
| issue_solutions = { | |
| "File is too long": "Consider breaking into smaller functions or modules", | |
| "Too many lines": "Refactor into smaller, focused functions", | |
| "Too many comments": "Ensure comments are meaningful and not redundant" | |
| } | |
| for issue in issues: | |
| if issue in issue_solutions: | |
| recommendations.append(issue_solutions[issue]) | |
| return recommendations | |
| if __name__ == "__main__": | |
| analyzer = PyPilotCodeAnalyzer() | |
| # Test with sample code | |
| sample_code = """ | |
| def calculate_factorial(n): | |
| if n == 0: | |
| return 1 | |
| else: | |
| return n * calculate_factorial(n-1) | |
| def main(): | |
| print(calculate_factorial(5)) | |
| if __name__ == "__main__": | |
| main() | |
| """ | |
| results = analyzer.comprehensive_analysis(sample_code) | |
| print("🔍 Code Analysis Results:") | |
| print(f"Functions: {results['ast_info']['functions']}") | |
| print(f"Metrics: {results['metrics']}") | |
| print(f"Quality Score: {results['quality']['quality_score']}") |