An extensible cyclomatic complexity analyzer for many programming languages including C/C++, Java, JavaScript, Python, Ruby, Swift, and more.
—
Extension framework for custom analysis metrics and output formats through the lizard_ext package. The system provides both built-in extensions for common analysis needs and an extensible architecture for custom extensions.
Functions for loading and managing extensions during analysis.
def get_extensions(extension_names):
"""
Loads and expands extension modules for analysis.
Args:
extension_names (list): List of extension names to load (e.g., ['nd', 'ns', 'wordcount'])
Returns:
list: List of extension objects ready for analysis
Example:
# Load nesting depth and nested structures extensions
extensions = get_extensions(['nd', 'ns'])
results = lizard.analyze_files(['app.py'], exts=extensions)
"""Built-in formatters for generating analysis reports in various formats.
def print_xml(results, options, _, total_factory):
"""
Formats and prints XML output in cppncss-compatible format.
Args:
results: Iterator of analysis results
options: Configuration options object
_: Unused parameter (for interface compatibility)
total_factory: Factory function for creating total results
Returns:
int: Exit code (0 for success)
"""
def print_csv(results, options, _, total_factory):
"""
Formats and prints CSV output with function metrics.
Args:
results: Iterator of analysis results
options: Configuration options object
_: Unused parameter
total_factory: Factory function for creating total results
Returns:
int: Exit code (0 for success)
"""
def print_checkstyle(results, options, _, total_factory, file=None):
"""
Formats and prints Checkstyle XML output for CI integration.
Args:
results: Iterator of analysis results
options: Configuration options object
_: Unused parameter
total_factory: Factory function for creating total results
file: Output file object (optional, defaults to stdout)
Returns:
int: Exit code (0 for success)
"""
def html_output(result, options, *_):
"""
Generates HTML reports using Jinja2 templates.
Args:
result: Analysis results object
options: Configuration options
Returns:
str: HTML report content
"""
def csv_output(result, options):
"""
Generates CSV format output with function metrics.
Args:
result: Analysis results object
options: Configuration options
Returns:
str: CSV formatted output
"""
def xml_output(all_result, verbose):
"""
Generates cppncss-compatible XML output.
Args:
all_result: Aggregated analysis results
verbose (bool): Include detailed function information
Returns:
str: XML formatted output
"""
def checkstyle_output(all_result, verbose):
"""
Generates Checkstyle XML format output.
Args:
all_result: Aggregated analysis results
verbose (bool): Include detailed information
Returns:
str: Checkstyle XML formatted output
"""Smart file handling utilities with encoding detection.
def auto_open(*args, **kwargs):
"""
Smart file opening with UTF-8 BOM detection and encoding fallback.
Args:
*args: Arguments passed to open()
**kwargs: Keyword arguments passed to open()
Returns:
file object: Opened file with appropriate encoding
Example:
with auto_open('data.txt', 'r') as f:
content = f.read()
"""
def auto_read(filename):
"""
Smart file reading with fallback encoding handling.
Args:
filename (str): Path to file to read
Returns:
str: File content with detected encoding
Example:
content = auto_read('source_file.py')
print(f"File length: {len(content)} characters")
"""Built-in extensions for specialized code analysis metrics.
class LizardExtension:
"""
Nesting Depth (ND) extension for analyzing maximum nesting depth.
Command-line: -N, --ND
Threshold: DEFAULT_ND_THRESHOLD = 7
Function Info Added:
max_nesting_depth: Maximum nesting depth in function
"""class LizardExtension:
"""
Nested Structures (NS) extension for counting nested control structures.
Command-line: --NS
Threshold: DEFAULT_NS_THRESHOLD = 3
Function Info Added:
max_nested_structures: Count of nested control structures
"""class LizardExtension:
"""
Word Count extension for generating tag clouds from code.
Command-line: -Ewordcount
Features:
- Counts word occurrences across codebase
- Generates HTML tag cloud visualization
- Filters common programming keywords
- Cross-file analysis and aggregation
"""class LizardExtension:
"""
Duplicate code detection extension.
Command-line: -Eduplicate
Features:
- Detects copy-paste code blocks
- Configurable similarity thresholds
- Hash-based duplicate identification
"""Base classes for creating custom extensions.
class ExtensionBase:
"""
Base class for all lizard extensions.
Methods to override:
__call__(self, tokens, reader): Process tokens during analysis
set_args(parser): Add command-line arguments
cross_file_process(fileinfos): Process results across multiple files
"""Complete list of built-in extensions with their capabilities:
# Core Analysis Extensions
class LizardExtension: # lizardnd.py
"""Nesting depth analysis (max_nesting_depth metric)"""
class LizardExtension: # lizardns.py
"""Nested structures counting (max_nested_structures metric)"""
class LizardExtension: # lizardmccabe.py
"""McCabe complexity metrics"""
class LizardExtension: # lizardmodified.py
"""Modified complexity calculations"""
# Code Quality Extensions
class LizardExtension: # lizardduplicate.py
"""Duplicate code detection and reporting"""
class LizardExtension: # lizardduplicatedparamlist.py
"""Duplicate parameter list detection"""
class LizardExtension: # lizardboolcount.py
"""Boolean complexity counting"""
class LizardExtension: # lizardcomplextags.py
"""Complex tag analysis"""
# Statement and Flow Extensions
class LizardExtension: # lizardexitcount.py
"""Exit/return statement counting (exit_count metric)"""
class LizardExtension: # lizardgotocount.py
"""Goto statement counting"""
class LizardExtension: # lizardstatementcount.py
"""Statement counting and analysis"""
# Language-Specific Extensions
class LizardExtension: # lizardcpre.py
"""C preprocessor directive filtering"""
class LizardExtension: # lizardignoreassert.py
"""Assert statement handling and filtering"""
class LizardExtension: # lizardnonstrict.py
"""Non-strict parsing mode"""
# Analysis and Reporting Extensions
class LizardExtension: # lizardwordcount.py
"""Word frequency analysis and tag cloud generation"""
class LizardExtension: # lizardio.py
"""I/O operation analysis"""
class LizardExtension: # lizarddependencycount.py
"""Dependency counting and analysis"""
class LizardExtension: # lizardoutside.py
"""External scope analysis"""
class LizardExtension: # lizarddumpcomments.py
"""Comment extraction and dumping"""import lizard
# Use nesting depth extension
extensions = lizard.get_extensions(['nd'])
results = lizard.analyze(['src/'], exts=extensions)
for file_info in results:
for func in file_info.function_list:
if hasattr(func, 'max_nesting_depth'):
print(f"{func.name}: ND={func.max_nesting_depth}")import lizard
# Combine multiple extensions
extensions = lizard.get_extensions(['nd', 'ns', 'exitcount'])
results = lizard.analyze(['src/'], exts=extensions)
for file_info in results:
for func in file_info.function_list:
metrics = []
if hasattr(func, 'max_nesting_depth'):
metrics.append(f"ND={func.max_nesting_depth}")
if hasattr(func, 'max_nested_structures'):
metrics.append(f"NS={func.max_nested_structures}")
if hasattr(func, 'exit_count'):
metrics.append(f"Exits={func.exit_count}")
print(f"{func.name}: {', '.join(metrics)}")import lizard
# Equivalent of: lizard -Ewordcount -Eduplicate -N src/
lizard.main(['-Ewordcount', '-Eduplicate', '-N', 'src/'])
# Multiple output formats with extensions
lizard.main(['-Ewordcount', '--xml', '-N', 'src/'])from lizard_ext import html_output, csv_output
import lizard
# Generate analysis results
extensions = lizard.get_extensions(['nd', 'ns'])
results = list(lizard.analyze(['src/'], exts=extensions))
# Create custom options object
class Options:
def __init__(self):
self.verbose = True
self.fields = ['nloc', 'ccn', 'max_nesting_depth']
options = Options()
# Generate HTML report
html_report = html_output(results, options)
with open('analysis_report.html', 'w') as f:
f.write(html_report)
# Generate CSV data
csv_data = csv_output(results, options)
with open('analysis_data.csv', 'w') as f:
f.write(csv_data)from lizard_ext import auto_open, auto_read
# Smart file reading with encoding detection
try:
content = auto_read('source_file_with_unicode.py')
print(f"Successfully read {len(content)} characters")
except Exception as e:
print(f"Failed to read file: {e}")
# Smart file opening
with auto_open('output.txt', 'w', encoding='utf-8') as f:
f.write("Analysis results with unicode: 你好 world")Install with Tessl CLI
npx tessl i tessl/pypi-lizard