A fast, memory-safe static call graph analyzer for Python, written in Zig.
Calligrapher analyzes Python code to extract call graphs enriched with cyclomatic complexity metrics, control flow analysis, and powerful query operations. Built with tree-sitter for fast, error-tolerant parsing.
- π― Python Call Graph Extraction: Functions, classes, methods, parameters, and calls
- π Multi-File Analysis: Project scanning, import resolution, cross-module call graphs
- π Module Dependencies: Dependency graphs, coupling analysis, instability metrics
- π Cyclomatic Complexity: Automatic computation for all functions and methods
- π Control Flow Analysis: Loop depth, nesting levels, and branch tracking
- π€ Multiple Export Formats: JSON, DOT (GraphViz), and Mermaid
- π Query Operations: Find callers, callees, paths, and symbol search
- π Project Metrics: Statistics, distribution analysis, and complexity hotspots
- β‘ High Performance: <50ms for small files, linear scaling for projects
- π Memory Safe: Zero leaks, zero panics, comprehensive testing
Prerequisites:
- Zig 0.13.0 or later
Build from source:
git clone https://github.com/rand/calligrapher.git
cd calligrapher
zig buildBinary available at zig-out/bin/calligrapher.
# Analyze a Python file and generate call graph with metrics
zig build run -- enrich examples/python/minimal/project.py -o output.json
# Analyze entire project directory (multi-file)
zig build run -- enrich examples/python/multi_module/ -o project_output.json
# Export project manifest
zig build run -- enrich ./my_project --manifest -o manifest.json
# Generate GraphViz visualization
zig build run -- enrich examples/python/with_classes/shapes.py --format=dot -o graph.dot
dot -Tpng graph.dot -o graph.png
# Generate Mermaid diagram
zig build run -- enrich examples/python/with_types/types_demo.py --format=mermaid -o diagram.mmd
# Query operations
zig build run -- query output.json find Circle
zig build run -- query output.json callers module.function
zig build run -- query output.json path from_func to_funcAfter running enrich, you'll see project metrics:
Project Metrics Summary
=======================
Complexity Distribution:
Low (1-5): 15 functions (75.0%)
Moderate (6-10): 4 functions (20.0%)
High (11-20): 1 function (5.0%)
Very High (21+): 0 functions (0.0%)
Statistics:
Mean complexity: 4.2
Median complexity: 3.0
Std deviation: 2.1
Top 5 Most Complex Functions:
1. module.process_data (complexity: 12)
2. module.validate_input (complexity: 8)
...
- QUICKSTART.md (824 lines) - Complete user guide with examples and troubleshooting
- API.md (1,000+ lines) - Developer reference for library integration and extension
- CHANGELOG.md - Release history and upgrade notes
- STATUS.md - Project status and milestone tracking
Structured data with symbols, call graph, complexity metrics, and control flow:
zig build run -- enrich file.py -o output.jsonVisual graphs with complexity-based coloring:
zig build run -- enrich file.py --format=dot -o graph.dot
dot -Tpng graph.dot -o graph.pngGitHub/GitLab compatible diagrams:
zig build run -- enrich file.py --format=mermaid -o diagram.mmd# Find symbols by name (partial match)
zig build run -- query output.json find symbol_name
# Find who calls this function
zig build run -- query output.json callers module.function
# Find what this function calls
zig build run -- query output.json callees module.function
# Find shortest path between functions
zig build run -- query output.json path from_func to_func
# Find all paths (depth-limited to 10)
zig build run -- query output.json allpaths from_func to_funcCyclomatic Complexity Ranges:
- 1-5: Low (simple, easy to test)
- 6-10: Moderate (acceptable)
- 11-20: High (consider refactoring)
- 21+: Very high (difficult to maintain)
Control Flow Metrics:
- Maximum loop depth
- Maximum nesting level
- Conditional branch count
Project Statistics:
- Mean, median, standard deviation
- Complexity distribution
- Top N most complex functions
- Small files (<100 LOC): <50ms
- Medium files (100-1K LOC): 50-200ms
- Large files (1K-10K LOC): 200ms-2s
- Memory usage: <100MB for typical projects
See PERFORMANCE.md for detailed benchmarks.
# Run all tests
zig build test
# Run release testing script
./scripts/test_release.sh
# Run performance benchmarks
./scripts/benchmark.shTest Coverage:
- 50+ unit and integration tests
- Automated CI on every commit
- Memory leak audit (zero leaks)
- Error handling review (zero panics)
The examples/python/ directory contains sample projects:
- minimal: Basic Python project
- with_imports: Import handling
- with_classes: OOP patterns with inheritance
- with_types: Type annotations
- multi_module: Multi-file project structure
Each example includes expected output for validation.
Calligrapher uses a modular pipeline architecture:
Input Python β Tree-sitter Parser β Symbol Extraction β Name Resolution
β
Complexity Computation
β
Call Graph Construction
β
Export (JSON/DOT/Mermaid) or Query
Modules:
- Core: Graph data structures (symbols, nodes, edges)
- Parser: Tree-sitter bindings and query system
- Extractors: Language-specific symbol extraction
- Resolution: Scope-based name resolution
- Integration: Bridges extraction and resolution
- Export: Multi-format serialization
- Query: Graph analysis operations
- Metrics: Project-level statistics
See API.md for detailed architecture documentation.
- Single-file processing: Multi-file analysis planned for v0.2.0
- Python-only: Additional languages (Rust, JS, TS) planned for v0.3.0
- Static analysis only: No dynamic/runtime analysis
- Import resolution: Limited to stdlib and relative imports
- Query depth: Limited to 10 for performance
- Multi-file project analysis
- Cross-module dependency graphs
- Package support (init.py)
- Enhanced import resolution
- Rust language support
- JavaScript/TypeScript support
- Additional complexity metrics
- Stable API
- Complete language coverage
- Production-grade performance
See PROJECT_PLAN.md for detailed roadmap.
Contributions welcome! See API.md for guides on:
- Adding new languages (step-by-step tutorial)
- Adding new export formats
- Extending functionality
Please open an issue or PR referencing relevant items in STATUS.md.
- Memory Safety: Comprehensive audit (750+ lines documented), zero leaks found
- Error Handling: Zero panics in production code, consistent error messages
- Testing: 50+ tests, 100% coverage of major operations
- CI/CD: Automated testing on every commit
- Performance: Baseline established, benchmarks documented
- ~13,000 lines of Zig code
- 38 source files
- 50+ tests
- 8 major modules
- Language: Zig 0.13.0
- Parser: Tree-sitter (vendored Python grammar v0.25.9)
- Design: Modular architecture with clear layer separation
- Memory: Arena allocators, string interning, RAII patterns
- Complexity: Linear time for most operations
- Primary Developer: Rand Arete
- Development Assistance: Claude Code
- Built With: Zig and Tree-sitter
Calligrapher is distributed under the MIT License.
- Documentation: QUICKSTART.md and API.md
- Issues: Report bugs at https://github.com/rand/calligrapher/issues
- Discussions: Ask questions in GitHub Discussions
Version 0.1.0 | October 13, 2025 | Initial Release