Code Metrics in Python - comprehensive tool for computing various software metrics
npx @tessl/cli install tessl/pypi-radon@6.0.0A comprehensive Python code analysis tool that computes various software metrics from source code to assess code quality and complexity. Radon calculates McCabe's cyclomatic complexity, raw metrics (SLOC, comments, blank lines), Halstead metrics for software complexity measurement, and the Maintainability Index for overall code maintainability assessment.
pip install radonimport radonFor specific analysis modules:
from radon import complexity, raw, metrics, visitorsFor command-line interface:
from radon.cli import program, Configfrom radon.complexity import cc_visit, cc_rank
from radon.raw import analyze
from radon.metrics import mi_visit, h_visit
# Analyze cyclomatic complexity
code = '''
def example_function(x, y):
if x > 0:
if y > 0:
return x + y
else:
return x - y
else:
return 0
'''
# Get complexity blocks
blocks = cc_visit(code)
for block in blocks:
print(f"{block.name}: {block.complexity} ({cc_rank(block.complexity)})")
# Get raw metrics
raw_metrics = analyze(code)
print(f"Lines of Code: {raw_metrics.loc}")
print(f"Logical Lines: {raw_metrics.lloc}")
print(f"Comments: {raw_metrics.comments}")
# Get maintainability index
mi_score = mi_visit(code, multi=True)
print(f"Maintainability Index: {mi_score}")
# Get Halstead metrics
halstead = h_visit(code)
print(f"Halstead Volume: {halstead.total.volume}")
print(f"Halstead Difficulty: {halstead.total.difficulty}")Radon provides a layered architecture for code analysis:
McCabe's cyclomatic complexity analysis for measuring code complexity and maintainability. Provides complexity scoring, ranking (A-F grades), and detailed block-level analysis for functions, methods, and classes.
def cc_visit(code, **kwargs): ...
def cc_visit_ast(ast_node, **kwargs): ...
def cc_rank(cc): ...
def average_complexity(blocks): ...
def sorted_results(blocks, order=SCORE): ...Analysis of basic code metrics including lines of code (LOC), logical lines of code (LLOC), source lines of code (SLOC), comments, blank lines, and multi-line strings for comprehensive code statistics.
def analyze(source): ...
class Module: ... # namedtuple with loc, lloc, sloc, comments, multi, blank, single_commentsSoftware complexity measurement based on operators and operands analysis. Calculates vocabulary, length, volume, difficulty, effort, time, and bug predictions using Halstead's software science metrics.
def h_visit(code): ...
def h_visit_ast(ast_node): ...
class HalsteadReport: ... # namedtuple with h1, h2, N1, N2, vocabulary, length, etc.Compound metric combining Halstead volume, cyclomatic complexity, and lines of code to determine overall code maintainability. Uses the same formula as Visual Studio's maintainability index calculation.
def mi_visit(code, multi): ...
def mi_compute(halstead_volume, complexity, sloc, comments): ...
def mi_parameters(code, count_multi=True): ...
def mi_rank(score): ...Low-level AST visitor classes for custom analysis and integration. Provides the foundation for all radon analysis capabilities with extensible visitor pattern implementation.
class ComplexityVisitor(CodeVisitor): ...
class HalsteadVisitor(CodeVisitor): ...
class Function: ... # namedtuple representing function blocks
class Class: ... # namedtuple representing class blocksComprehensive CLI with four analysis commands (cc, raw, mi, hal) supporting multiple output formats, configuration files, and batch processing capabilities for integration with CI/CD pipelines.
class Config: ...
def cc(paths, **kwargs): ...
def raw(paths, **kwargs): ...
def mi(paths, **kwargs): ...
def hal(paths, **kwargs): ...# Raw metrics container
Module = namedtuple('Module', [
'loc', # Lines of Code (total lines)
'lloc', # Logical Lines of Code
'sloc', # Source Lines of Code (non-blank, non-comment)
'comments', # Comment lines
'multi', # Multi-line strings (docstrings)
'blank', # Blank lines
'single_comments' # Single-line comments
])
# Function/method representation
Function = namedtuple('Function', [
'name', # Function name
'lineno', # Starting line number
'col_offset', # Column offset
'endline', # Ending line number
'is_method', # Boolean: is this a method?
'classname', # Class name if method, None if function
'closures', # List of nested functions
'complexity' # Cyclomatic complexity score
])
# Class representation
Class = namedtuple('Class', [
'name', # Class name
'lineno', # Starting line number
'col_offset', # Column offset
'endline', # Ending line number
'methods', # List of methods
'inner_classes', # List of nested classes
'real_complexity' # Class complexity score
])
# Halstead metrics report
HalsteadReport = namedtuple('HalsteadReport', [
'h1', # Number of distinct operators
'h2', # Number of distinct operands
'N1', # Total number of operators
'N2', # Total number of operands
'vocabulary', # h1 + h2
'length', # N1 + N2
'calculated_length', # h1 * log2(h1) + h2 * log2(h2)
'volume', # N * log2(h)
'difficulty', # h1 / 2 * N2 / h2
'effort', # D * V
'time', # E / 18 seconds
'bugs' # V / 3000 (error estimate)
])
# Combined Halstead results
Halstead = namedtuple('Halstead', [
'total', # HalsteadReport for entire file
'functions' # List of HalsteadReport for each function
])